Java 一笔交易用于多个JpaRepositories';方法
我有一些自动连接的接口。它们中的每一个都有针对不同实体的“更新”hql方法。我从服务的方法调用这些方法 如果其中一个失败,我如何使它们在一个事务中执行以回滚所有数据 服务有属性@service&@transactional,但它没有帮助 ------------------------更新 这里有一个例子。repository1.updateMethod()和repository2.updateMethod()工作正常,repository3.save因约束错误引发异常。结果,我看到repository1和repository2方法的结果被保存。我需要它向后滚动Java 一笔交易用于多个JpaRepositories';方法,java,spring,jpa,transactions,Java,Spring,Jpa,Transactions,我有一些自动连接的接口。它们中的每一个都有针对不同实体的“更新”hql方法。我从服务的方法调用这些方法 如果其中一个失败,我如何使它们在一个事务中执行以回滚所有数据 服务有属性@service&@transactional,但它没有帮助 ------------------------更新 这里有一个例子。repository1.updateMethod()和repository2.updateMethod()工作正常,repository3.save因约束错误引发异常。结果,我看到reposi
@ Service
@ Transactional(rollbackFor = {RuntimeException.class})
public SomeService {
@ Autowired SomeRepository repository1;
@ Autowired AnotherRepository repository2;
@ Autowired ThirdRepository repository3;
...
@ Transactional(rollbackFor = {RuntimeException.class})
public void SomeMethod(SomeEntity obj, String someNewValue) {
try {
repository1.updateMethod();
repository2.updateMethod();
obj.setValue(someNewValue);
repository3.save(obj);
} catch (Exception ex) {
throw new RuntimeException();
}
}
}
我想我找到了一个解决方案,但我仍然不明白为什么它不能与默认用法一起工作 首先,我在applidationData.xml声明了JpaTransactionManager
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
在我的代码之前,我添加了:
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("TxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus ts = jtm.getTransaction(def);
最后呢
jtm.commit(ts);
现在,如果某个方法产生异常,它将在最后一行抛出,所有更新都将回滚。这就是我需要的。但是,正如我所说的,我仍然不明白为什么它在默认情况下不起作用。Exapndong on't not work'并发布一些代码可能会有所帮助。请参阅我前面的评论:在服务方法级别指定
@transactional
应该使该事务下的任何内容都具有事务性,除非您在子事务上将事务类型设置为“Requires New”或“Not Supported”,这将在其自己的事务中运行这些事务。您是否通过在CRUD中抛出一些东西来测试这一点,然后检查事务是否一直回滚?您能分享一些代码吗?@CodeChimp第一条消息已更新,我添加了示例并扩展了我的意思。您如何获得该服务的引用?向我们展示使用该服务的代码。主题观察之一:在抛出RuntimeException
时,应该包含异常。您实际上是在吞并原因,只会得到一个空白的运行时异常
。另外,您是否有理由将事务限制为RuntimeException
?似乎您需要所有异常…不确定用runtimeexception
包装它是否能为您带来任何好处。可能您的设置有问题。我认为@Transactional
在封面下使用了AOP,所以你可能遗漏了一些关键的东西?此外,如果要回滚异常,则需要将ts.rollback()封装在它自己的try/catch中。否则,异常将吞噬首先导致回滚的异常。您最终会对原始异常的真正原因视而不见。
jtm.commit(ts);