source

Spring에서 트랜잭션을 사용할 때 사후 커밋 만들기

ittop 2023. 8. 20. 12:40
반응형

Spring에서 트랜잭션을 사용할 때 사후 커밋 만들기

Spring Platform Transaction Manager를 사용하여 트랜잭션 커밋 및 롤백을 수동으로 수행한 특정 이유로 인해 트랜잭션이 커밋된 후 사후 커밋 작업이 수행되도록 후크를 설정해야 합니다.

확인 결과:

 void commit(TransactionStatus status) throws TransactionException;

예외가 발생하지 않는 한 거래가 성공적이었다고 가정하는 것 외에 어떻게 판단할 수 있는지 알 수 없습니다.

그리고 저는 AOP를 하나의 옵션으로 사용할 수 있지만, 프로그램에서 콜백 방법을 사용하는 것은 어떨까요?

더 간단한 방법으로 원하는 것을 정확히 얻을 수 있습니다.

와 함께TransactionSynchronizationManager현재 트랜잭션에 대한 정보를 얻을 수 있는 정적인 방법이 있으며 등록할 수 있습니다.TransactionSynchronization이것은 당신이 그것을 부르는 대로 사후 커밋을 자동으로 수행할 수 있게 해줍니다.

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization(){
           void afterCommit(){
                //do what you want to do after commit
           }
})

트랜잭션 동기화는 스레드 단위로 이루어집니다(기본 웹 요청에서는 문제가 되지 않는 경우가 많습니다).

Grovek의 답변과 Alex의 의견에 대한 공로를 인정합니다. 결합된 제안은 인터넷에서 찾기 어려운 견고하고 깨끗한 솔루션을 제공하기 때문입니다.

Spring 4+.에서 콜백이 필요한 경우 사용@Transactional메소드를 성공적으로 커밋한 후 메소드의 시작 부분에 추가합니다.

@Service
public class OneService {

    @Autowired
    OneDao dao;

    @Transactional
    public void a transactionalMethod() {
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){
            public void afterCommit(){
                //do stuff right after commit
                System.out.println("commit!!!");

            }
        });
        //do db stuff
        dao.save();
    }
}

봄 4.2 이후 주석 기반 구성을 사용하여 사후 커밋 이벤트(또는 더 일반적으로 트랜잭션 동기화 이벤트(예: 롤백)에 대한 수신기를 정의할 수 있었습니다.이는 코어 스프링의 이벤트 처리를 기반으로 합니다.단위 테스트에서 활성화되지 않을 가능성이 높은 TransactionSynchronizationManager에 대한 직접적인 종속성을 피하므로 이 접근 방식을 사용하여 코드를 테스트하는 것이 더 쉽습니다.트랜잭션 서비스가 이벤트를 게시하고 이벤트를 수신할 때 수신기가 올바른 작업을 수행하는지 쉽게 테스트할 수 있습니다.

추가 작업 없이 설정 방법은 다음과 같습니다.

이 예에서는 다음과 같이 가정합니다.Customer실체와 aCustomerRepository(및 ORM과 함께 제공).

먼저 새 이벤트 유형이 필요합니다.NewCustomerEvent:

// NewCustomerEvent.java
// Just a regular pojo for the event
public class NewCustomerEvent {

    public String email;

    // constructor, setters and getters omitted
}

그런 다음 을 사용하여 수신기를 정의합니다. 기본적으로 이것은 성공적인 커밋 후에 실행되지만 이것은 다음을 사용하여 변경될 수 있습니다.phase매개변수:

// NewCustomerEventListener.java
@Component
public class NewCustomerEventListener {

    @TransactionalEventListener
    public void handleNewCustomerEvent(NewCustomerEvent newCustomerEvent) {
        // handle new customer event
    }
}

마지막으로 모든 거래 명세서가 전송되면 게시를 호출하는 를 사용하여 거래 서비스를 확장합니다.

// CustomerRespositoryService.java
@Service
public class CustomerRepositoryService {

    @Inject
    private ApplicationEventPublisher applicationEventPublisher;

    @Inject
    private CustomerRepository customerRepository;

    @Transactional
    public void createCustomer(String email) {
        Customer customer = new Customer(email);
        customerRespotory.save(customer);
        applicationEventPublisher.publish(new NewCustomerEvent(email));
    }

}

참고 항목:

특정한 이유로 인해 프로젝트 중 하나에서 사용해야 했습니다.PlatformTransactionManager그래서 어쩔 수 없이 사용했습니다.org.springframework.transaction.support.TransactionTemplate.

http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/transaction/support/TransactionTemplate.html

Platform Transaction Manager를 올바르게 구현한 경우 수동 커밋/롤백을 수행할 필요가 없습니다.트랜잭션의 소스 코드 이상템플릿은 더 구체적인 것이 필요할 때 도움이 될 수 있습니다.

쉽게 사용할 수 있습니다.

config.xml

<bean name="transactionTemplate"
            class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="platformTransactionManager"/>
</bean>

MyServiceImpl.java


@서비스public 클래스 MyServiceMyServiceImplementsMyService}
@자동 배선사적 거래템플릿 트랜잭션템플릿;
공용 엔티티가 Tx(최종 긴 ID)가 있는 무언가를 가져옵니다.
반품 거래템플릿.execute(새 트랜잭션 콜백<엔티티>() {@재지정공용 엔티티 DoInTransaction(거래 상태) {//TODO 구현}});}

언급URL : https://stackoverflow.com/questions/15026142/creating-a-post-commit-when-using-transaction-in-spring

반응형