0

現在、JCA rar を使用して、Glassfish 4 に Jackrabbit 2.6.4 をデプロイしています。

私は MySql を使用しており、Glassfish でデータソースを構成してデータベースにアクセスしています。RepositoryManager を構成するときに、Jackrabbit の repository.xml で同じデータソースを使用します。

@Resource アノテーションを介して、トランザクションを自動的に開始しないコンテナー管理 Bean にリポジトリーを注入すると、すべてが期待どおりに機能します。

@Resource アノテーションを介して EJB にリポジトリを挿入すると (コンテナ管理のトランザクションが発生します)、リポジトリを使用しようとすると、次のスタック トレースが表示されます。

javax.resource.spi.LocalTransactionException: com.sun.gjc.spi.LocalTransactionImpl.commit(LocalTransactionImpl.java:112) で autocommit=true の場合、com.sun.enterprise.resource.ConnectorXAResource.commit(ConnectorXAResource) でコミットを呼び出せません.java:124) ... 原因: java.sql.SQLException: Can't call commit when autocommit=true at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927) at 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: Can com.sun.enterprise.resource.ConnectorXAResource.handleResourceException(ConnectorXAResource.java:115) で com.sun.enterprise.resource.ConnectorXAResource.commit(ConnectorXAResource.java:126) で autocommit=true の場合、コミットを呼び出さない ... ] ]115) com.sun.enterprise.resource.ConnectorXAResource.commit(ConnectorXAResource.java:126) で ... ]]115) com.sun.enterprise.resource.ConnectorXAResource.commit(ConnectorXAResource.java:126) で ... ]]

Jackrabbit のドキュメントを見ると、次のように記載されています。

データベース持続性マネージャーを使用する場合、構成済みのデータベース接続が外部トランザクション マネージャーの制御下にないようにする必要があります。Jackrabbit は、より高いレベルで分散 XA トランザクション サポートを実装し、基盤となるデータベース接続を完全に制御できることを期待しています。

この場合、Jackrabbit と Glassfish を構成して、コンテナー管理トランザクションと Jackrabbit 管理トランザクションの両方が同じグローバル トランザクションに参加できるようにするにはどうすればよいですか?

Jackrabbit JCA アダプターとデータソース接続プールの両方を XA トランザクションを使用するように設定しようとしました。また、Jackrabbit JCA プロパティ bindSessionToTransaction を true に設定しました。これらのどちらも機能しませんでした。

4

1 に答える 1

0

試行錯誤の結果、次のアプローチにたどり着きました。

  1. Jackrabbit リポジトリ テーブルへのアクセスに使用される JDBC 接続プールを glassfish に作成します。
  2. リソース タイプを javax.sql.DataSource に設定し、「非トランザクション接続」を有効にします。
  3. Jackrabbit JDBC 接続プールへのアクセスに使用できる JDBC リソースを作成します。Jackrabbit repository.xml のこのリソースで定義されている JNDI 名を使用して、永続化マネージャーなどを構成します。
  4. Jackrabbit-jca リソース アダプタを使用してコネクタ接続プールを作成する
  5. トランザクション サポートを XATransaction に設定する
  6. プロパティ「bindSessionToTransaction」を追加し、true に設定します
  7. リポジトリを EJB に挿入するために使用できるコネクタ リソースを作成する

これをステートレス EJB でテストしたところ、エラーなく動作しました。

また、タイプ javax.sql.DataSource の 2 つ目の JDBC 接続プールと、アプリケーションの他のテーブルを維持する別のデータベースを指す JDBC リソースを作成し、データソースを使用する persistence.xml を作成しました。

次に、アプリケーション データベースのリポジトリとテーブルの両方を (JPA を使用して) 変更し、トランザクションがロールバックされた場合、リポジトリとアプリケーション テーブルの両方の変更が正しくロールバックされることを確認しました。

Jackrabbit がデータベース接続を完全に制御しながら、XA リソースとしてコンテナー管理トランザクションに参加できるため、これは正しいアプローチだと思います。

2 番目のデータソースを XADataSource と非 XA DataSource の両方としてテストしたところ、両方のアプローチが機能しました。トランザクションには XA 以外の DataSource が他になく、LLR (Logging Last Resource) を介してグローバル トランザクションに参加するため、XADataSource である必要はないと思います。

更新 1:

リポジトリのデータソースをバイパスし、JDBC URL をリポジトリ xml で直接構成することで、これを機能させることもできます。これの利点の 1 つは、リポジトリをクラスタ化するときに、Glassfish インスタンスごとにデータソースを作成する必要がなく、repository.xml をコピーしてクラスタ ノード ID を変更するだけでよいことです。

于 2013-10-29T16:53:10.607 に答える