有没有办法“重播”交易? 我的意思是,有时我得到RollbackException并回滚事务。然后我可以“克隆”事务并再次尝试,或者一旦调用回滚,事务就丢失了吗? 我真的需要这些更改,并且真的不想跟踪每个更改以便稍后重新运行...
感谢, udi
答案 0 :(得分:0)
为什么你首先得到例外?在我看来,这是问题的症结所在。
你是否依赖乐观的写作?如果是这样,那么你将不得不以某种形式的循环包装你的数据库写入,包含(可能)退避和一些重试。不幸的是,您不能自动执行此操作(除非您调查某种形式的AOP解决方案,使用重试策略包装数据库写入?)
答案 1 :(得分:0)
这取决于交易的来源。在Java / JDBC中,事务与连接相关联。您可以通过将setAutoCommit()
设置为false来启动一个(否则,每个语句都会成为它自己的小事务)。
在事务失败后,没有任何东西阻止您重新使用连接(即您调用了回滚)。
使用Spring时,事情变得更加棘手。 Spring将您的方法包装在事务处理程序中,并且此处理程序尝试从方法中抛出的异常中猜测它应该如何处理当前事务。接下来的问题是:哪个包装器创建了当前的事务?我刚才有一个案例,我会调用一个方法foo()
,然后调用bar()
,@Transactional
。
我想从bar()
中的foo()
抓取错误并将其保存到数据库中。这不起作用,因为事务是为foo()
创建的(因此我仍处于Spring认为被bar()
中的异常破坏的事务中)并且它不会让我保存错误。< / p>
解决方案是创建baz()
,将其设为@Transactional(propagation=Propagation.REQUIRES_NEW)
并从foo()
调用它。 baz()
将获得一个新的,新的事务,并且即使从foo()
已经有一个(损坏的)事务调用它,也可以写入数据库。
答案 2 :(得分:0)
另一种方法是使用JDBC savepoints部分回滚。