2017-09-10 60 views
0

我想通過使用一個微框架來編寫我的下一個微型Java Web應用程序。例如。 SparkJooby。問題是它們都不支持JTA,所以我需要使用其中一個第三方庫。我搜索了開源JTA實現,發現了兩個:AtomikosBitronix。看起來後面的項目略有放棄,所以我決定和Atomikos一起去。不幸的是,文檔很少,所以我無法找到我的問題的答案。如何在Web應用程序中正確使用獨立的TransactionManager?

這是用例。假設我們有哪些方法應該在單個事務下執行的兩項DAO類:

class SomeService { 

    // both injected by Guice 
    private FooDao fooDao; 
    private BarDao barDao; 

    public void someMethod() { 
     // both methods should be executed in a single transaction 
     fooDao.insert(new Foo()); 
     barDao.insert(new Bar()); 
    } 
} 

我從來沒有用過javax.transaction API直接/手動之前(你知道的聲明性事務與春季很簡單的),所以我有點困惑。 JTA提供兩個通用抽象(UserTransactionTransactionManager),它們都有處理JDBC事務的方法。據我瞭解,TransactionManager通過使用ThreadLocal變量來操作UserTransaction對象。因此UserTransaction應該是線程限制的,並且TransactionManager應該是線程安全的。我對麼?

所以有幾種方法可以:

  1. 我可以注入到事務管理我的服務(通過吉斯),並直接使用它。
  2. 我可以通過公共靜態變量共享TransactionManager。
  3. 我可以創建UserTransaction提供者/工廠(通過Guice)並從中獲取對象。

這是正確的/最佳實踐?

另一個問題,如果有人熟悉Atomikos是它提供了兩個事務管理器實現(可能更多):J2eeTransactionManagerUserTransactionManager。同樣的文檔太稀缺了,所以除了JNDI之外我沒有看到任何區別。我想UserTransactionManager應該夠我的目的,但描述的狀態下

J2eeTransactionManager

事務管理的實現,應該由J2EE 應用程序使用。

..沒有任何解釋。

ps。對不起,我的英語不好,我知道。

+0

您打算使用哪種交易資源?簡單的SQL數據庫JMS-隊列/主題? JPA是參與的,ORM是hibernate還是eclipselink?你打算使用分佈式事務嗎?你是否希望能夠使用事務屬性註釋類或方法,或者「bean管理」事務是否足夠? – aschoerk

+0

@aschoerk我只需要在單個事務中從不同的DAO類中執行兩個方法。我使用簡單的普通JDBC - 不包括JMS,JPA,XA事務或任何其他涉及JEE的東西。但是,我確實使用DI。現在我只想了解如何正確共享TM或UserTransaction實例。聲明式事務管理不是必需的。我想,只要我明白如何利用TM,它就足夠簡單,可以通過反射代理編寫定製的聲明式事務。 – Evan

+0

爲什麼不共享JDBC連接?我認爲這對你應該是足夠的。只要簡單的「BEGIN TRANSACTION」和「COMMIT TRANSACTION」可以用於你的dao-calls,如果它們使用相同的連接。就是這樣,你的TM在這種情況下會爲你做。 – aschoerk

回答

0

Ок,因爲沒有人回答我,挖成源代碼之後,我想我已經準備好回答我的問題:

  1. 兩個Atomikos公司和Bitronix的TM實現爲單身[1][2]
  2. Atomikos和Bitronix TM都是線程安全的。特別是,Atomikos使用內部同步,而Bitronix根本不會在線程之間共享狀態。
  3. AtomikosBitronix TMs實現了兩個(oops)TransactionManager和UserTransaction接口,所以基本上不管你要用哪一個接口。即使你看到Atomikos UserTransactionImp類,你也會看到它在內部實例化並使用相應的TransactionManager實現。

因此,有一個TM-per-webapp實例是安全的,您可以以任何方式共享這個實例。由於Atomikos TM supposed to be instantiated最好通過依賴注入來分享它。 Bitronix TM可以通過public static method與任何其他單身人士一起使用。

此外,您可以通過JNDI管理事務。您可以在Java Persistence with Hibernate書籍源代碼中找到示例。

+0

我只是好奇,這些解決方案如何保證,您的JDBC語句真的在通過調用begin和commit定義的transactioncontextes中執行?您的JDBC實現是否也發現了這些TM並在那裏註冊(好吧,這似乎是您使用AtomicDatasource的Atomic-Solution)?您是否配置TM以便它們同步JDBC連接? – aschoerk

+1

@aschoerk每個TM僅適用於來自同一供應商的javax.sql.DataSource實現。例如Atomikos TM必須使用AtomikosNonXADataSourceBean或AtomikosXADataSourceBean。 Bitronix TM必須使用Bitronix的PoolingDataSource等。當你使用Spring的時候,你可以通過傳遞給DataSourceTransactionManager來實際使用任意的數據源實現,但是當你使用某種前面提到的TM時,這不是一個交易。 – Evan

+0

他們共享連接狀態的方式是供應商特定的。我沒挖得這麼深。但如果你看看更簡單的[TM實現](https://github.com/odnoklassniki/one-datasource/blob/master/src/one/datasource/DataSourceImpl.java#L261),你會發現它可能通過JNDI工作。 – Evan