如何在Web应用程序中正确使用独立的TransactionManager?

时间:2017-09-10 13:51:24

标签: java java-ee dependency-injection jta atomikos

我想通过使用一个微框架编写我的下一个小型Java webapp。例如。 SparkJooby。问题是它们都不支持JTA,所以我需要使用第三方库之一。我已经开始搜索开源JTA实现,并找到了两个:AtomikosBitronix。似乎后一个项目略有放弃,所以我决定选择Atomikos。不幸的是,文档很少,所以我无法找到问题的答案。

这是用例。假设我们有两个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(你知道Spring的声明性事务非常简单)所以我有点困惑。 JTA提供了两个通用抽象(UserTransactionTransactionManager),它们都有处理JDBC事务的方法。据我所知,TransactionManager通过使用ThreadLocal变量来操作UserTransaction对象。因此,UserTransaction应该是线程限制的,并且TransactionManager应该是线程安全的。我是对的吗?

所以有几种可能的方法:

  1. 我可以将TransactionManager注入我的服务(通过Guice)并直接使用它。
  2. 我可以通过公共静态变量共享TransactionManager。
  3. 我可以创建一个UserTransaction提供者/工厂(通过Guice)并从中获取对象。
  4. 哪个是正确/最佳实践?

    另一个问题是,熟悉Atomikos的人是否提供了两个事务管理器实现(可能更多):J2eeTransactionManagerUserTransactionManager。文档再次缺乏,所以除了JNDI之外,我没有看到任何差异。我想UserTransactionManager应该足够我的目的,但描述说明如下

      

    J2eeTransactionManager

         

    J2EE应该使用的TransactionManager的实现   应用

    ..没有任何解释。

    PS。对不起,我的英语不是很清楚。

1 个答案:

答案 0 :(得分:0)

Ок,因为没有人回答我,在深入研究源代码后,我想我已经准备好回答我自己的问题了:

  1. Atomikos和Bitronix TM都实现为单身[1][2]
  2. Atomikos和Bitronix TM都是线程安全的。特别是,Atomikos使用内部同步,而Bitronix根本不在线程之间共享状态。
  3. AtomikosBitronix TM都实现了两个(oops)TransactionManager和UserTransaction接口,因此基本上与您将使用哪个无关。即使您查看Atomikos UserTransactionImp类,您也会看到它在内部实例化并使用相应的TransactionManager实现。
  4. 因此,拥有一个TM-per-webapp实例是安全的,您可以按照自己喜欢的方式进行共享。从Atomikos TM supposed to be instantiated开始,最好通过依赖注入来共享它。 Bitronix TM可以通过public static method用作任何其他单例。

    此外,您可以通过JNDI管理交易。您可以在 Java Persistence with Hibernate 书籍源代码中找到一个示例。