Java 为什么@Transactional在另一个提交失败时不回滚一个提交?

Java 为什么@Transactional在另一个提交失败时不回滚一个提交?,java,junit,transactions,spring-transactions,Java,Junit,Transactions,Spring Transactions,所以我有一门课: @服务 公共类MyService{ @自动连线 私人回购; @自动连线 私人回购b repoB; @交易的 public void storeEntitySomeEntity e{ 雷帕·萨维; 其他实体o=具有实体e的dosomething; 萨维奥报告; } } 我的方法storeEntity对两个不同的数据源执行两次保存。我希望,如果保存到repoB失败,或者doSomethingWithEntity失败,repoA.save将回滚 我想写一个小测试来确保这种行为: @R

所以我有一门课:

@服务 公共类MyService{ @自动连线 私人回购; @自动连线 私人回购b repoB; @交易的 public void storeEntitySomeEntity e{ 雷帕·萨维; 其他实体o=具有实体e的dosomething; 萨维奥报告; } } 我的方法storeEntity对两个不同的数据源执行两次保存。我希望,如果保存到repoB失败,或者doSomethingWithEntity失败,repoA.save将回滚

我想写一个小测试来确保这种行为:

@RunWithSpringRunner.class @春靴测试 公共类MyServiceForTransactionTest{ @自动连线 私人MyService主体; @自动连线 私人回购; @蚕豆 私人回购b repoB; @试验 公共无效报告不应保存条目{ //给定 当报告保存任何时,则通过数据库中的非法状态异常; repob.count.isEqualTo0的资产; //什么时候 某物实体e=。。。 subject.storeentity; //然后 资产repoa.count.isEqualTo0; } } 这将不起作用,因为会引发异常并使测试失败。当我用try/catch包围调用时,我的断言将失败,并显示一条消息,即repoA有1个条目。如何解决这个问题

我也试过:

@试验 公共无效报告不应保存条目{ //给定 当报告保存任何时,则通过数据库中的非法状态异常; repob.count.isEqualTo0的资产; //什么时候 某物实体e=。。。 试一试{ subject.storeentity; }捕获异常e{ //这里有一些输出 } //然后 资产repoa.count.isEqualTo0; } 断言失败。我也试过:

@试验 公共无效报告不应保存条目{ //给定 当报告保存任何时,则通过数据库中的非法状态异常; repob.count.isEqualTo0的资产; //什么时候 某物实体e=。。。 subject.storeentity; } @之后 公共空间拆除{ //然后 资产repoa.count.isEqualTo0; } }
也失败了。找到1条记录,但我希望@Transactional应该回滚。

当您通过Spring管理事务时,实际上是在使用抽象。对于通常称为资源的单个数据源,本地事务事务的启动/提交/回滚将按预期工作,但如果您使用两个不同的数据源,那么您将需要一个事务管理器,能够像或在开源世界中执行分布式事务。在EE应用服务器环境中,此功能由服务器本身提供。这是一篇非常古老的文章,值得一读。它使用一个数据库和一个消息代理参与分布式事务,但概念是相同的——关键是多个资源。有关Bitrionix和Spring的示例配置,请检查。

尝试将@Transactional添加到测试方法中检查哦,拜托,我的案例真的那么具体吗?常规的Spring配置无法处理这个问题?Spring事务管理只是一个抽象和策略层。对于单个数据库,它将委托给使用JDBC、JPA等的任何机制。但是对于分布式事务,您必须告诉Spring您的事务管理器是什么。查看本文,了解更多关于事务协调的解释,以防在不容易的工作中使用多个资源,这就是为什么您有非常详细的标准X/OpenXA来描述所涉及的协议。这些标准的实现已经在EE服务器weblogic/Jboss/TomEE等中提供,因此Spring不会重新发明轮子。还有一些开源实现,比如Bitronix。这也是一个很好的文章