Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 一笔交易用于多个JpaRepositories';方法_Java_Spring_Jpa_Transactions - Fatal编程技术网

Java 一笔交易用于多个JpaRepositories';方法

Java 一笔交易用于多个JpaRepositories';方法,java,spring,jpa,transactions,Java,Spring,Jpa,Transactions,我有一些自动连接的接口。它们中的每一个都有针对不同实体的“更新”hql方法。我从服务的方法调用这些方法 如果其中一个失败,我如何使它们在一个事务中执行以回滚所有数据 服务有属性@service&@transactional,但它没有帮助 ------------------------更新 这里有一个例子。repository1.updateMethod()和repository2.updateMethod()工作正常,repository3.save因约束错误引发异常。结果,我看到reposi

我有一些自动连接的接口。它们中的每一个都有针对不同实体的“更新”hql方法。我从服务的方法调用这些方法

如果其中一个失败,我如何使它们在一个事务中执行以回滚所有数据

服务有属性@service&@transactional,但它没有帮助

------------------------更新

这里有一个例子。repository1.updateMethod()和repository2.updateMethod()工作正常,repository3.save因约束错误引发异常。结果,我看到repository1和repository2方法的结果被保存。我需要它向后滚动

@ 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);