2017-09-14 123 views
0

我正在使用JBOSS EAP 6.x.即使已声明事务属性,TransactionRequiredException

我有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

+1

看起来像是在第一次merge()之后由于某些原因,事务已经结束。 merge()是entityManager的方法还是你的方法? – Ermal

+0

好抓..合并是我们的框架方法,它基于某些逻辑在内部创建某些版本化记录和历史记录,并使用实体管理器的合并执行插入和更新。我将尝试在具有事务属性的新方法中移动第二个合并,并在此处进行更新。 –

+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) 
} 
0

在你的情况的解决方案是为封闭新事务里面你merge()方法,例如:

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
public void updateMessageStatus(Entity entity) { 
    merge(entity); 
} 

而且到处打电话updateMessageStatus()不直接merge()


为什么你的代码是工作?

@TransactionAttribute(REQUIRED)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)