2015-04-07 93 views
2

我有一個問題。我正在使用java應用程序服務器(sap netweaver)與我正在使用ejb 3.0爲什麼不提交Requires_New事務?

所以我想數據庫一個接一個地插入。因爲我的數據太多,我不得不分數據。所以我做了一個測試代碼,它確實有效,但它並沒有像我想的那樣工作。

我想爲每個部分創建一個新的事務,當然在最後方法(事務)應該是提交。

示例代碼如下;

package com.transaction.jobs; 

import javax.ejb.Local; 

/** 
* 
* @author muratdemir 
*/ 
@Local 
public interface TestTransactionLocal { 

    public void onStart(); 

    public void insertObject(int i); 
} 

package com.transaction.jobs; 

import com.transaction.service.DatabaseServiceLocal; 
import com.transaction.entity.Item; 
import com.transaction.entity.Logger; 
import java.util.Date; 
import javax.annotation.Resource; 
import javax.ejb.EJB; 
import javax.ejb.EJBContext; 
import javax.ejb.Stateless; 
import javax.ejb.TransactionAttribute; 
import javax.ejb.TransactionAttributeType; 
import javax.ejb.TransactionManagement; 
import javax.ejb.TransactionManagementType; 

/** 
* 
* @author muratdemir 
*/ 
@Stateless 
@TransactionManagement(TransactionManagementType.CONTAINER) 
public class TestTransactionService implements TestTransactionLocal { 

    @EJB 
    DatabaseServiceLocal databaseService; 

    @Resource 
    EJBContext context; 

    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public void onStart() { 
     try { 
      System.out.println("START"); 

      Logger log1 = new Logger(new Date(), ">>>T1 commiting"); 
      databaseService.create(log1); 

      System.out.println(">>>T1 committing"); 

      Thread.sleep(5000); 

      for (int i = 1; i < 10; i++) { 
       System.out.println("Call new Transaction"); 

       insertObject(i); 

       Thread.sleep(2000); 
      } 

      Thread.sleep(5000); 

      Logger log2 = new Logger(new Date(), "<<<T1 commiting"); 

      databaseService.create(log2); 

      System.out.println("<<<T1 committing"); 

      Thread.sleep(5000); 
      System.out.println("END"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      context.setRollbackOnly(); 
     } 

    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    public void insertObject(int i) { 
     try { 
      System.out.println("New Transaction Start i:" + i); 

      Item item = new Item(new Date(), "Name_" + i); 

      databaseService.create(item); 

      System.out.println("commit transaction: " + i); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      context.setRollbackOnly(); 
     } 
    } 

} 

的insertObject(REQUIRES_NEW)函數是工作,但它並沒有犯。它等待提交其他onStart(REQUIRED)函數。如果mytimer函數結束,則插入函數將全部提交。

爲什麼新交易沒有提交?

注意:如果我更改onStart函數的事務屬性REQUIRED爲NOT_SUPPORTED,它的工作原理是我想要的。爲什麼它以這種方式工作?

回答

2

您必須使用SessionContext#getBusinessObject方法初始化另一個TestTransactionLocal。這樣你的TestTransactionLocal實例將遵循@TransactionAttribute註解。

@Resource 
private SessionContext sessionContext; 

private TestTransactionLocal local; 

@PostConstruct 
void init() { 
    local = sessionContext.getBusinessObject(TestTransactionLocal.class); 
} 

然後通過這個新的參考調用insertObject():

local.insertObject(i); 

看到這個博客帖子:http://www.adam-bien.com/roller/abien/entry/how_to_self_invoke_ejb

+0

是的,它的工作! –

2

您直接調用prepare()方法,因此不考慮事務註釋。您需要通過自己的界面(即myTestTimerLocal.prepare())調用它,以獲得任何交易影響。

+0

我更新的問題。我試過'@EJB TestTransactionLocal local; '和'local.insertObject(i);'但沒有奏效。 –

相關問題