我正在使用JBOSS EAP 6.x.
我有ejb.method1()
,其中注明了交易属性@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
ejb.method2()
内部的,其中使用事务属性@TransactionAttribute(TransactionAttributeType.SUPPORTS)
我从ejb.method2()
ejb.method1()
如下所示
ejb.method() {
//some operation
ejb.method2();
//some operation
}
ejb2.method2() {
//some operation
merge(entity1); // no error here
try {
sendMessageToMQ // no error here} catch(Exception e) {
entity.setStatus("SUCCESS");
} catch() {Expcetion) {
entity1.setStatus("ERROR");
} finally {
merge(entity1); // Throwing Caused by: javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context
}
}
如果执行在一分钟内完成,则代码可以正常工作,但是当它花费大约3分钟时,它会因以下异常而失败。事务超时设置为15分钟。
Caused by: javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context
答案 0 :(得分:0)
在新方法中提取第二个合并方法并使用事务属性对其进行注释后,它对我有用。调用提取方法的方法已经使用Transaction Attribute Supports进行了注释。
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
ejb.method() {
//some operation
ejb.method2();
//some operation
}
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
ejb2.method2() {
//some operation
merge(entity1); // no error here
try {
sendMessageToMQ // no error here} catch(Exception e) {
entity.setStatus("SUCCESS");
} catch() {Expcetion) {
entity1.setStatus("ERROR");
}
thisService.updateMessageStatus(entity1);
}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void updateMessageStatus(Entity entity) {
merge(entity)
}
答案 1 :(得分:0)
在您的情况下,解决方案是将您的merge()
方法包含在新交易中,例如:
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void updateMessageStatus(Entity entity) {
merge(entity);
}
并且到处呼叫updateMessageStatus()
而不是直接merge()
。
为什么您的代码有效?
@TransactionAttribute(REQUIRED)
上的{p> updateMessageStatus()
说"如果来电者没有任何交易,则创建一个新的"。
正如我在评论中所写,第一次交易在第一次调用合并后结束。在这一行之后:
merge(entity1); // no error here
当您致电updateMessageStatus()
时,REQUIRED
会打开一个新事务,并在updateMessageStatus()
结束时提交/回滚。
您只是打开一个新的交易,因为您在第二次通话中没有任何有效的交易。这就是为什么我的建议是将updateMessageStatus()
注释为REQUIRES_NEW
关于SUPPORTS
的另一个观察是(假设您在ejb2.method2()
内呼叫ejb.method()
)
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
ejb.method() {
ejb2.method2();
}
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
ejb2.method2() {
thisService.updateMessageStatus(entity1);
}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void updateMessageStatus(Entity entity) {
}
如果仅从@TransactionAttribute(SUPPORTS)
调用该方法, ejb2.method2()
没有意义,因为ejb.method()
已经有了一个事务。我会让默认的@TransactionAttribute(REQUIRED)