2

我们有一个已经使用 JPA 和 guice-persist 的现有 j2se 项目。现在,因为我们要添加 JMS 功能,所以需要 2-phase-commit 和 JTA。我们将使用 bitronix 事务管理器,因为没有容器(如 spring)。

据我了解,我们要做的第一件事就是将持久化单元的事务类型从RESSOURCE-LOCAL更改为JTA,因为我们希望数据库事务投票支持提交而不是提交。收集所有选票后,提交在第 2 阶段完成。

使用 guice-persist,我们将@Transactional注解用于应该在单个事务中运行的方法。提供JPAPersistModule了一个 EnitiyManagerFactory ,它用于 guice-persist 内部类,就像JpaLocalTxnInterceptor包装了带注释的方法一样。

现在我得到了例外

java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
at org.hibernate.ejb.AbstractEntityManagerImpl.getTransaction(AbstractEntityManagerImpl.java:1009)
at com.google.inject.persist.jpa.JpaLocalTxnInterceptor.invoke(JpaLocalTxnInterceptor.java:57)
    ...

因为对提供的实体管理器的JpaLocalTxnInterceptor调用。getTransaction()

我现在很困惑。有什么方法可以将 guice-persist 与 JTA 一起使用,或者我们真的必须从项目中删除 guice-persist 吗?或者,如果我们想做 JTA(使用 Bitronix),是否有任何替代 guice-persist 的方法?

4

1 回答 1

2

有过类似的情况。在我们的例子中,我们使用的是 Guice + Jooq。我们想要 Jooq 是因为我们有一个大型的遗留 Rails DB 并且想要精细的控制和速度。我们之所以选择 Guice 而不是 Spring,是因为我们觉得它是一个更好的框架,而且速度更快,而且我们喜欢编译时检查。

我们不能在 Jooq 中使用 Guice,所以我们:

  • 使用 Atomikos JTA(免费版)
  • 编写了我们自己的@Transactional AOP注解拦截器;
  • 我们的可注入服务为我们的 jooq 处理器提供 java.sql.Connection,但始终提供一个 Atomikos DataSource bean

我们基本上修改了这段代码:

http://www.dailyjavatips.com/2011/10/24/database-transactions-google-guice-aop/

因此,该示例使用常规 JDBC Tx,但我们对其进行了修改,因此它将使用 Atmomikos 的 JTA 感知 Tx。

奇迹般有效!

大杰

于 2013-03-25T18:40:04.067 回答