【问题标题】:Spring Boot propagate transaction (and db connection) to @Async methodSpring Boot 将事务(和数据库连接)传播到 @Async 方法
【发布时间】:2016-10-26 07:01:22
【问题描述】:

我们遇到了以下问题:我们有一些服务 bean 进行一些处理,并将迭代一个集合并为每个条目启动一个异步线程,如下所示:

@Service
public class ServiceBean {
  @Autowired
  private AsyncHandler asyncHandler;

  public void doService(Set<?> theSet) {
    for (Object obj : theSet) {
      Future<?> future = asyncHandler.doHandle(obj);
      // ...
    }
    // wait for all futures to complete
  }
}

@Service
public class AsyncHandler {
  @Async
  public Future<?> doHandle(Object object) {
    // dosth
    return future;
  }
}

现在我们看到每个线程都将拥有自己的事务和数据库连接,这将导致连接池非常快地运行为空。

跨所有线程共享事务的理想方式是什么?

提前致谢!

【问题讨论】:

  • 你不能。事务和连接存储在 ThreadLocal 中。您不能让事务跨越多个线程。限制可以拥有的并发线程数量是最简单的解决方案。
  • “你不能”......我打赌你可以,也许定制 Spring 是必要的。有了 ThreadLocal 中的事务,就有可能在新线程中获取和设置它。
  • M. Dienum 正确我已经删除了我的答案。
  • 除非您传递连接和事务状态,否则您不能。您需要重新实现整个事务策略。使用开箱即用的支持,您根本无法实现这一目标。

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


【解决方案1】:

跨所有线程共享事务的理想方式是什么?

不要那样做。这使得很难理解发生了什么。事务附加到创建它的线程是有原因的。我猜你的计划是启动所有这些异步线程,然后等待它们完成发送提交信号。

如果你不这样做,谁来完成交易?如果一个线程回滚事务,其他仍在使用它的线程会发生什么?显然你可以传递Connection,但我希望无论如何都会序列化,因为大多数连接实现都在各个地方使用synchronized

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-31
    • 2019-04-12
    • 2018-10-10
    • 1970-01-01
    • 2020-07-07
    • 2020-02-26
    • 1970-01-01
    • 2020-09-03
    相关资源
    最近更新 更多