2016-11-15 175 views
1

我想了解EJB事務管理。我寫了下面的代碼,並在WebSphere自由部署EJB事務管理

@Stateless 
@TransactionManagement(TransactionManagementType.BEAN) 
public class BookRepositoryBean { 

    @Resource(lookup = "jdbc/mydb") 
    private DataSource dataSource; 

    public void create(List<Book> books) { 

    try { 
    for(Book book: books) { 
     Connection con = dataSource.getConnection(); 
     PreparedStatement stmt = con.preparedStatement("insert into ...."); 
     stmt.setString(1, ...); 
     stmt.executeUpdate(); 
    } 
    } catch(SQLException e) { 
    throw new RuntimeException(e.getMessage()); 
    } 
} 

我server.xml中看起來像下面

<dataSource jndiName="jdbc/mydb" transactional="false"> 
.... 
</dataSource> 

我手動插入其中有一個主鍵約束的表中的記錄,然後試圖運行我的代碼堅持兩個記錄,其中一個是重複記錄,另一個是新記錄。

我試着用不同的選項,並觀察到以下

  1. 服務器XML數據源:事務=假
    TransactionManagementType = BEAN
    結果:1/2記錄依然存在。由於沒有交易 管理代碼編寫,這是預期的。

  2. 服務器XML數據源:事務=真正
    TransactionManagementType = CONTAINER
    結果:0/2記錄依然存在。由於交易管理已啓用 已插入0條記錄。

  3. 服務器XML數據源:事務=假
    TransactionManagementType = CONTAINER
    結果:1/2記錄持續

  4. 服務器XML數據源:事務=真正
    TransactionManagementType = BEAN
    結果:1/2記錄持續存在。我瞭解到,由於我在代碼級別關閉了 事務管理,因此1條記錄一直存在。

  5. 服務器XML數據源:事務=真正
    刪除@Stateless和@TransactionManagement註釋
    結果:0/2記錄依然存在。

在情況3,我不明白爲什麼插入1條記錄。我假設容器級別的事務管理只在代碼中啓用時才起作用,並且在容器級別啓用。我對嗎?

在情況5中,我不明白爲什麼0記錄在類不是EJB時已被保留。我總是認爲事務管理僅適用於EJB。這個測試證明我錯了。現在我不明白爲什麼要在普通的java類中選擇EJB。

任何人都可以解釋一下嗎?

回答

2

關於#5,通過刪除註釋並使其成爲正常的java類,它將在調用者的事務和上下文下運行。調用者是否使用容器管理事務處理另一個EJB?

+0

是的調用者是一個EJB。感謝您指點。我將嘗試通過刪除調用者的無狀態註釋來再次進行測試。 –

+0

我刪除了調用者上的無狀態註釋並進行了測試。 1/2記錄被保留。感謝您指出問題。 –

1
  • 服務器XML數據源:事務=假
    TransactionManagementType = CONTAINER
    結果:1/2記錄持續

    在情況3中,我不明白爲什麼1個記錄被插入。我假設容器級別的事務管理只在代碼中啓用時才起作用,並且在容器級別啓用。我對嗎?
  • 即使容器在這個EJB管理交易,如果資源不能夠參與交易(即交易= FALSE),那麼每個操作單獨執行。插入重複密鑰失敗,並插入其他密鑰成功。

    +0

    因此,在第五種情況下,如果我在jboss或任何其他沒有LTE的應用程序服務器上運行相同的代碼,是否會保留一條記錄? –

    +0

    原來我的情況#5不正確。這不是LTC的工作方式,所以我已經刪除了我的答案。 –