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));
}
}
참고 항목:
- https://dzone.com/articles/simpler-handling-of-asynchronous-transaction-bound
- https://dzone.com/articles/transaction-synchronization-and-spring-application
특정한 이유로 인해 프로젝트 중 하나에서 사용해야 했습니다.PlatformTransactionManager
그래서 어쩔 수 없이 사용했습니다.org.springframework.transaction.support.TransactionTemplate
.
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
'source' 카테고리의 다른 글
Oracle SQL Developer 소문자 자동 완성(대문자는 어떻습니까) (0) | 2023.08.20 |
---|---|
Entity Framework 7 데이터베이스 우선 POCO 생성기가 있습니까? (0) | 2023.08.20 |
ScrollView 내의 RecyclerView가 원활하게 스크롤되지 않음 (0) | 2023.08.20 |
파워셸을 사용하여 IIS 버전 찾기 (0) | 2023.08.20 |
jQuery를 사용하여 클래스가 있는 조상이 있는지 확인합니다. (0) | 2023.08.20 |