2014-10-16 136 views
0

從方法a()調用方法b()時,新事務是否啓動? 或者這只是一個來自對象的方法調用而註解不起作用? 如果是這樣,那該怎麼辦呢?從方法a()調用方法b()時新的事務是否開始?

@Stateless 
public class TestBean { 
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
    public void a() { 
     b(); 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    public void b() { 
    } 
} 
+0

它是依靠什麼庫/框架您使用。在平面java當然不是。 – talex 2014-10-16 10:16:31

+0

[本地方法調用中的EJB事務]的可能重複(http://stackoverflow.com/questions/427452/ejb-transactions-in-local-method-calls) – Gas 2014-10-16 13:44:53

回答

4

您可以使用TransactionSynchronizationRegistry資源通過查詢當前交易狀態輕鬆檢查。這裏是我試圖上Wildfly 8.1的示例:

1 - 注入TransactionSynchronizationRegistry作爲資源:

@Resource 
TransactionSynchronizationRegistry txReg; 

2 - 一個小的輔助查詢當前tranaaction狀態並返回人類可讀字符串:

private String getTXStatus() 
{ 
    int txStatus = this.txReg.getTransactionStatus(); 
    switch (txStatus) 
    { 
     case Status.STATUS_ACTIVE: 
      return "STATUS_ACTIVE"; 
     case Status.STATUS_COMMITTED: 
      return "STATUS_COMMITTED"; 

     case Status.STATUS_COMMITTING: 
      return "STATUS_COMMITTING"; 
     case Status.STATUS_MARKED_ROLLBACK: 
      return "STATUS_MARKED_ROLLBACK"; 
     case Status.STATUS_NO_TRANSACTION: 
      return "STATUS_NO_TRANSACTION"; 
     case Status.STATUS_PREPARED: 
      return "STATUS_PREPARED"; 
     case Status.STATUS_PREPARING: 
      return "STATUS_PREPARING"; 
     case Status.STATUS_ROLLEDBACK: 
      return "STATUS_ROLLEDBACK"; 
     case Status.STATUS_ROLLING_BACK: 
      return "STATUS_ROLLING_BACK"; 
     case Status.STATUS_UNKNOWN: 
      return "STATUS_UNKNOWN"; 
     default: 
      return "Unknown(" + txStatus + ")"; 
    } 

3 - 現在你可能會樂器的商業方法與一些快速和骯髒的記錄(以及從來沒有把System.out.println()在生產EJB代碼

! 10
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
public void a() 
{ 
    System.out.println("+++ a()"); 
    System.out.println("TX status is " + getTXStatus()); 
    b(); 
    System.out.println("TX status is " + getTXStatus()); 
    System.out.println("--- a()"); 
} 

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
public void b() 
{ 
    System.out.println("+++ b()"); 
    System.out.println("TX status is " + getTXStatus()); 
    System.out.println("--- b()"); 
} 

4 - 現在,我們可以從一些客戶端調用a()然後b()

String beanName = "ejb:EJB3/MOD3//SagMalWas!de.treufuss.ejb3project.client.HelloWorldRemote"; 
HelloWorldBIF bif = HelloWorldBIF.class.cast(jndiContext.lookup(beanName)); 
bif.a(); 
bif.b(); 

它產生在服務器控制檯輸出如下:

12:58:33,123 INFO [stdout] (EJB default - 3) +++ a() 
12:58:33,123 INFO [stdout] (EJB default - 3) TX status is STATUS_NO_TRANSACTION 
12:58:33,123 INFO [stdout] (EJB default - 3) +++ b() 
12:58:33,123 INFO [stdout] (EJB default - 3) TX status is STATUS_NO_TRANSACTION 
12:58:33,123 INFO [stdout] (EJB default - 3) --- b() 
12:58:33,124 INFO [stdout] (EJB default - 3) TX status is STATUS_NO_TRANSACTION 
12:58:33,124 INFO [stdout] (EJB default - 3) --- a() 

12:58:33,127 INFO [stdout] (EJB default - 4) +++ b() 
12:58:33,128 INFO [stdout] (EJB default - 4) TX status is STATUS_ACTIVE 
12:58:33,128 INFO [stdout] (EJB default - 4) --- b() 

這證明沒有開始事務,爲調用b()a

附錄

您可以通過EJB上下文中的bean業務接口調用b()方法強制創建新事務。要做到這一點...

1 - 注入EJB上下文資源

@Resource 
private SessionContext ctx; 

2 - 通過業務接口調用b()方法:

@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
public void a() 
{ 
    System.out.println("+++ a()"); 
    System.out.println("TX status is " + getTXStatus()); 
    // Direct invocation is treated as POJMC (plain old java method call 
    b(); 
    // Indirect invocation via EJB context 
    HelloWorldLocal thisBean = ctx.getBusinessObject(HelloWorldLocal.class); 
    thisBean.b(); 
    System.out.println("TX status is " + getTXStatus()); 
    System.out.println("--- a()"); 
} 
2

沒有交易將開始。這被視爲內部方法並與當前交易相關聯。由於您的a()方法聲明瞭NOT_SUPPORTED事務屬性,所以在調用方法a()b()期間不會創建事務。當客戶端調用該方法時,將遵守事務屬性,因此如果某個組件將調用testBean.b(),則無論是否存在事務,都將創建新事務。

相關問題