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