2013-10-28 53 views
0

我目前已经使用JCA rar在Glassfish 4中部署了Jackrabbit 2.6.4。容器管理器事务和JackRabbit

我使用MySql并在Glassfish中配置了一个数据源来访问数据库。配置RepositoryManager时,我在Jackrabbit repository.xml中使用相同的数据源。

如果我通过@Resource注释将资源库注入到不会自动启动事务的容器管理bean中,那么所有操作都按预期工作。

如果我通过注入@Resource注解一个仓库到EJB(这会导致容器管理的事务)我得到以下堆栈跟踪当我尝试使用的存储库:

javax.resource。 spi.LocalTransactionException:在autocommit = true时无法调用commit commit at com.sun.gjc.spi.LocalTransactionImpl.commit(LocalTransactionImpl.java:112) at com.sun.enterprise.resource.ConnectorXAResource.commit(ConnectorXAResource.java :124) ... 原因:java.sql.SQLException:autocommit = true时无法调用commit在com.mysql.jdbc.SQL上的 Error.createSQLException(SQLError.java:927) 在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:924) 在com.mysql.jdbc.ConnectionImpl.commit(ConnectionImpl.java:1724) 在COM。 sun.gjc.spi.LocalTransactionImpl.commit(LocalTransactionImpl.java:106) ... 72更多 ]] [2013-10-28T14:49:29.646-0700] [glassfish 4.0] [警告] [jts.unexpected_error_occurred_twopc_commit ] [javax.enterprise.system.core.transaction.com.sun.jts.jtsxa] [tid:_ThreadID = 33 _ThreadName = http-listener-1(3)] [timeMillis:1382996969646] [levelValue:900] [[ JTS5067:提交中发生意外错误 javax.transaction.xa.XAException:javax.resource.spi.LocalTransactionException:在com.sun中,当autocommit = true时,无法调用提交 。 enterprise.resource.ConnectorXAResource.handleResourceException(ConnectorXAResource.java:115) 在com.sun.enterprise.resource.ConnectorXAResource.commit(ConnectorXAResource.java:126) ... ]

综观Jackrabbit文档指出:

如果您使用数据库持久性管理器,则配置的数据库连接不得受外部事务管理器的控制。 Jackrabbit在更高层次上实现分布式XA事务支持,并期望完全控制底层数据库连接。

鉴于此,如何配置Jackrabbit和Glassfish以允许容器管理事务和Jackrabbit管理事务共同参与同一全局事务?

我曾尝试设置Jackrabbit JCA适配器和数据源连接池以使用XA事务。我还将Jackrabbit JCA属性bindSessionToTransaction设置为true。这些都没有奏效。

回答

0

一些试验和错误我想出了以下办法后:

  1. 创建GlassFish的JDBC连接池,用于访问兔崽子库表。
  2. 将资源类型设置为javax.sql.DataSource并启用'Non Transactional Connections'
  3. 创建一个可用于访问Jackrabbit JDBC连接池的JDBC资源。使用在兔崽子的repository.xml在此资源定义的JNDI名称来配置持久性管理等
  4. 使用兔崽子,JCA资源适配器
  5. 设置事务支持XATransaction
  6. 添加的属性创建连接器连接池“bindSessionToTransaction”,并将其设置为true
  7. 创建可用于存储库注入到一个EJB

我有一个无状态EJB测试这和它的作品没有错误连接器资源。

我还创建了第二个类型为javax.sql.DataSource的JDBC连接池和一个指向独立数据库的JDBC资源,该数据库维护应用程序其他表并创建使用数据源的persistence.xml。

然后,我修改了应用程序数据库(使用JPA)中的repo和表,并确认如果回滚事务,回滚和应用程序表上的更改都会正确回滚。

我相信这是正确的方法,因为它允许Jackrabbit完全控制它的数据库连接,但仍然作为XA资源参与容器管理事务。

我测试了第二个数据源都是XADataSource和非XA数据源,并且两种方法都有效。我认为它不需要成为XADataSource,因为事务中没有其他非XA DataSources,并且它通过LLR(记录上次资源)参与全局事务。

更新1:

原来你也可以得到这个绕过回购数据源,并直接在库中的XML配置JDBC URL的工作。这样做的一个好处是,在对不需要在每个Glassfish实例中创建数据源的repo进行群集时,您可以复制repository.xml并更改群集节点ID。