2013-02-22 52 views
15

由于某些原因,我使用Spring PlatformTransactionManager手动执行了事务提交和回滚,我需要做的是设置一个挂钩,以便在事务完成后发生提交后操作承诺。在Spring中使用事务时创建提交后提交

通过观察:

void commit(TransactionStatus status) throws TransactionException; 

我不能看到我怎么能确定交易比assumming它,所以如果没有expception抛出成功等。

而且我可以使用AOP作为一个选项,但是如何编程呢,也许使用回调方法呢?

回答

33

你可以得到你想要什么以更简单的方式,TransactionSynchronizationManagerTransactionSynchronization

With TransactionSynchronizationManager,你有静态方法来获取有关当前事务的信息,你可以注册一个TransactionSynchronization至极让你自动做一个提交后,你调用

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

请注意,TransactionSynchronization是基于每个线程基础(这对于基本Web请求通常不是问题)。

+0

好吧这似乎相当不错...所以如果它绑定到单线程,并且调用是递归的...说单线程启动一个事务注册同步(1 - 提交后),然后调用另一个方法谁加入该事务注册同步(2 - 提交后)....当它提交..我认为只有一个后提交同步会被解雇...因为他们被存储在一个集?..也许我错了我将不得不测试... – user1555190 2013-02-22 15:56:27

+0

'TransactionSynchronization'对象保持为线程列表,您可以使用'TransactionSynchronizationManager检索列表。 getSynchronizations()' – Grooveek 2013-02-22 15:58:52

+0

我相信它保持为一个集合,然后作为列表返回... Set synchs .............. return new ArrayList (synchs) .....即时通讯只是在提交后会想到两个... – user1555190 2013-02-22 16:09:39

1

在我的一个项目中,由于某些原因,我也不得不使用PlatformTransactionManager。所以我不得不使用org.springframework.transaction.support.TransactionTemplate

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

主要的好处是,如果您正确实施的PlatformTransactionManager,你不需要带手动理会提交/回滚。如果你需要更具体的东西,至少TransactionTemplate的源代码可以帮助你。

这是非常简单的使用方法:

config.xml中

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

MyServiceImpl.java

 

@Service 
public class MyServiceImpl implements MyService { 

    @Autowired 
    private TransactionTemplate transactionTemplate; 

    public Entity getSomethingWithTx(final long id) { 

     return transactionTemplate.execute(new TransactionCallback<Entity>() { 
      @Override 
      public Entity doInTransaction(TransactionStatus status) { 
       //TODO implement 
      } 
     }); 
    } 

+0

那真的事物的手工编码方面的帮助,但怎么可能告诉羯羊交易已经回滚或成功提交,我可以看到status.iscompleted()..但这可能意味着成功回滚或成功提交...? – user1555190 2013-02-22 14:48:51

+1

仅在两种情况下,事务将回滚到此处:回调代码会抛出一个异常,这会导致doInTransaction或存在隐式回滚调用(强烈建议不要并且可能会生成UnexpectedRollbackException)。因此,您可以放心地假设getSomethingWithTx没有抛出exceptin,事务成功提交。 – mrembisz 2013-02-22 15:23:04

6

感谢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(); 
    } 
} 
+1

感谢@Michail的回答。对于事务性回滚,此方法使用“afterCompletion(int status)”并检查状态== TransactionSynchronization。 STATUS_ROLLED_BACK – deep 2018-03-08 21:12:54