use*_*190 24 java spring transactions
由于某些原因,我已经手动执行了事务提交并使用Spring PlatformTransactionManager回滚,我需要做的是设置一个钩子,以便在事务提交后进行事后提交操作.
通过观察:
void commit(TransactionStatus status) throws TransactionException;
Run Code Online (Sandbox Code Playgroud)
我不知道如何确定一个事务是成功的,除了假设它,所以如果不抛出任何expception.
我可以使用AOP作为一个选项,但是如果使用AOP,可能会使用回调方法呢?
Gro*_*eek 47
你可以通过简单的方式得到你想要的东西,用TransactionSynchronizationManager和TransactionSynchronization
有了TransactionSynchronizationManager,您有静态方法来获取有关当前事务的信息,并且您可以注册一个TransactionSynchronization允许您在调用时自动执行提交后的方法
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization(){
void afterCommit(){
//do what you want to do after commit
}
})
Run Code Online (Sandbox Code Playgroud)
请注意,TransactionSynchronization基于每个线程(对于基本Web请求通常不是问题).
Mic*_*dis 15
感谢Grooveek的回答以及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();
}
}
Run Code Online (Sandbox Code Playgroud)
Fra*_*son 11
从 Spring 4.2 开始,可以使用基于注解的配置为提交后事件(或更一般的事务同步事件,例如回滚)定义侦听器。这是基于核心 spring 中的事件处理。使用这种方法测试代码更容易,因为您避免了对 TransactionSynchronizationManager 的直接依赖,它可能不会在单元测试中处于活动状态。您可以轻松测试您的事务服务是否发布了一个事件,以及您的侦听器在您收到一个事件时是否执行了正确的操作。
所以不用多说,这是如何设置它:
在这个例子中,我们假设你有一个Customer实体和一个CustomerRepository(以及与之配套的 ORM)。
首先你需要一个新的事件类型NewCustomerEvent:
// NewCustomerEvent.java
// Just a regular pojo for the event
public class NewCustomerEvent {
public String email;
// constructor, setters and getters omitted
}
Run Code Online (Sandbox Code Playgroud)
然后使用@TransactionalEventListener. 默认情况下,这将在成功提交后执行,但这可以使用phase参数进行更改:
// NewCustomerEventListener.java
@Component
public class NewCustomerEventListener {
@TransactionalEventListener
public void handleNewCustomerEvent(NewCustomerEvent newCustomerEvent) {
// handle new customer event
}
}
Run Code Online (Sandbox Code Playgroud)
最后,您使用一个ApplicationEventPublisher在发送完所有交易语句后调用 publish 的方法来扩充您的交易服务。
// 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));
}
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
| 归档时间: |
|
| 查看次数: |
25748 次 |
| 最近记录: |