Jakarta ee javaee中异步方法的事务管理

Jakarta ee javaee中异步方法的事务管理,jakarta-ee,asynchronous,transactions,Jakarta Ee,Asynchronous,Transactions,我们在无状态SessionBean中有一个性能不佳的业务方法。为了提高性能,我们希望将此业务方法拆分为几个异步方法调用 问题是这些异步方法必须在同一事务中运行(它们必须使用相同的JPA实体管理器)。就我对JavaEE规范的理解而言,使用容器管理的事务是不可能做到这一点的。是否可以使用bean管理的事务或其他机制来实现这一需求?无论是使用标准EJB还是任何扩展,都无法实现这一点。事务绑定到数据库连接,这意味着您必须在多个线程之间共享该连接。这不安全 此外,由于某些原因,异步代码可能会以大延迟执行,

我们在无状态SessionBean中有一个性能不佳的业务方法。为了提高性能,我们希望将此业务方法拆分为几个异步方法调用


问题是这些异步方法必须在同一事务中运行(它们必须使用相同的JPA实体管理器)。就我对JavaEE规范的理解而言,使用容器管理的事务是不可能做到这一点的。是否可以使用bean管理的事务或其他机制来实现这一需求?

无论是使用标准EJB还是任何扩展,都无法实现这一点。事务绑定到数据库连接,这意味着您必须在多个线程之间共享该连接。这不安全

此外,由于某些原因,异步代码可能会以大延迟执行,例如在高CPU负载下。这将使您的交易持续不必要的长时间

你有什么选择?首先,并行化SQL查询(尤其是写操作——您需要将它们包含在一个事务中)不会给您带来太多好处。数据库通常是I/O绑定的。只有当您有CPU密集型任务或正在等待某些任务时,并行化才值得您花费时间

在这两种情况下,重新设计代码以在多个线程中执行并行代码,并且只有一个writer线程来处理数据库和事务。例如,如果需要调用10个服务器,则收集响应并存储它们-生成10个线程/使用一个池,等待结果并将所有响应存储在一个线程中

另见

业务方法不会修改数据库。这是一个只读操作。问题是我们必须确保它在数据库的快照上运行。即,我们必须确保不考虑其他人在业务方法运行时对数据库所做的更改。因此,我们使用了一个“可重复读取”事务。它是一个MySQL InnoDB数据库>并行化SQL查询不会给您带来太多的好处-实际上,有时会。当你有一个具有大量并行IO容量的DB时,它确实会加快速度。我们构建这样的系统:(旧的例子,新的有3或4个RAID控制器,带有24到48个SSD)。在这种情况下,将大型查询分解为8个或更多并行查询可以显著提高性能和容量的总体利用率。