【问题标题】:Best way to impletent Java multithreading to prevent transaction rollback实现 Java 多线程以防止事务回滚的最佳方法
【发布时间】:2021-07-15 13:41:49
【问题描述】:

我有一个包含 4 个 DTO 的列表。我正在对列表中的每个 DTO 执行一些处理。如果假设其中一个 DTO 出现任何异常,则所有事务都会回滚(即使该过程对于其他 3 个 DTO 来说是成功的)。

我的代码如下所示:

@Transactional
public void processEvent(List<MyObject> myList){
   myList.forEach(dto -> process(dto));
}

public void process(MyObject dto){
//some code which calls another class marked as @Transactional
// and save the data processed to database
}

我想在一个单独的线程上为每个 DTO 执行这些过程,这样在一个线程中遇到的异常不会回滚所有 DTO 的事务。 还有没有办法在不同的线程上一个一个地处理这些 DTO,从而保持数据的一致性?

【问题讨论】:

  • 是什么让你觉得这段代码是多线程的?该代码没有任何多线程。如果您希望每个对象都有一个新事务,那么就这样做,创建一个新事务,这就是 REQUIRES_NEW 传播级别的用途。
  • @M.Deinum 我知道我的代码不是多线程的。我很困惑使我的代码多线程的最佳实践是什么,以便我为每个对象获得一个新事务(保持数据一致性)?
  • @YashAgarwal 。 . .您无需将代码设为多线程即可获得新事务。正如 M. Deinum 所说,只需使用 Spring @Transactional 注释的 propagation 属性即可。见这里:docs.spring.io/spring-framework/docs/current/javadoc-api/org/…。 . .
  • @MatheusCirillo 感谢您的澄清。之前我不确定如何处理这个问题。

标签: java multithreading spring-boot java-8 transactions


【解决方案1】:

只需将事务移动到使用 dto 调用的方法,另外我不确定它是否需要用于 dto 的事务。这看起来是一个不应该有任何事务注释的控制器。在服务中,一旦您将 dto 更改为实体并准备好保存它,您就可以放置注释。此外,如果您只是调用存储库的保存方法,则不需要在事务中,因为保存方法在存储库中具有注释。

public void processEvent(List<MyObject> myList){
   myList.forEach(dto -> process(dto));
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void process(MyObject dto){
//some code which calls another class marked as @Transactional
// and save the data processed to database
}

最后一个建议不要将@Transactional 放在类上,除非它们的 readOnly 参数设置为 true。然后您可以将@Transactional 放在执行任何CRUD 操作的方法上。

【讨论】:

    猜你喜欢
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 2010-12-14
    相关资源
    最近更新 更多