我有一个看起来像这样的课程:
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@Lock(LockType.WRITE)
@AccessTimeout(value = 20, unit = TimeUnit.MINUTES)
public class MyClass{
public void someLongRunningQuery(){
}
}
但是,这会失败:
org.jboss.resteasy.spi.UnhandledException: javax.ejb.EJBTransactionRolledbackException: Transaction rolled back
我可以通过添加此注释来解决此问题。
@TransactionTimeout(value = 20, unit = TimeUnit.MINUTES)
我的问题是 - 为什么jboss将此方法视为交易?我的理解是并发管理和事务管理是不同的事情。
答案 0 :(得分:0)
EJB规范中未定义事务超时处理,JBoss使用单独的事务管理模块来执行此操作。您的示例指向对单例的REST访问 - Singleton也是REST端点还是从某个REST端点bean调用?只是几个想法:
如果你有一个REST端点注入你的单例并调用长时间运行的op,那么@Stateless
bean是不是有机会?默认情况下,EJB bean是事务启用的,因此如果客户端(REST端点)启动事务(默认情况下它是@TransactionAttribute(REQUIRED)
),您的单例也将参与同一事务,但因为它的调用时间比默认事务超时值(300s)它导致事务回滚。如果您不需要在其余图层上执行交易,请尝试使用@TransactionAttribute(NOT_SUPPORTED)
来禁用它
如果从REST层调用这个长时间运行的op,最好不要使用@Asynchronous
并向客户端返回某种请求/作业句柄,以便它可以查询操作的状态而不是它完成后等待和阻塞?请记住,EJB是池化资源,因此多次调用此long操作可能会耗尽池并导致获取超时。