0

Spring トランザクションの概念を理解しようとしています。以下に示すように、2 つの異なるデータベース (iSeries と DB2) にデータを挿入する必要がありますが、iSeries バージョンは 2 フェーズ コミットをサポートしていません。要件は、両方の挿入が成功した場合にのみトランザクションをコミットする必要があり、それ以外の場合はロールバックする必要があることです。

Propagation を REQUIRED または REQUIRES_NEW として使用すると、「既存の 2 フェーズ対応リソースで 1 フェーズ対応リソースをコミットしようとする不正な試みが発生しました」というエラーが表示されます。

しかし、NOT_SUPPORTED または SUPPORTS を使用すると、正常に動作します (つまり、挿入の 1 つが失敗した場合、トランザクションはロールバックし、そうでない場合は、両方の挿入が成功した場合にコミットします)。

私の理解では、Propagation = SUPPORTS / NOT_SUPPORTED の場合、以下のシナリオではトランザクションは開始されません。したがって、2 つの異なるデータベースで両方の挿入が独立して発生する可能性があり、いずれかが失敗した場合、トランザクション全体がロールバックされるべきではありません。

しかし、 Propagation = SUPPORTS / NOT_SUPPORTED は私の要件に従って機能します。誰かがこれを説明できますか?前もって感謝します。

@Resource
private SessionFactory db2SessionFactory = null;

@Resource
private SessionFactory iSeriesSessionFactory = null;

@Transactional(propagation = Propagation.REQUIRED)
public void insert()
{
   insertDB1();
   insertDB2();
}

insertDB1()
{
   db2SessionFactory .getCurrentSession().saveOrUpdate(obj1);
}

insertDB2()
{
   iSeriesSessionFactory.getCurrentSession().saveOrUpdate(obj2);
}
4

2 に答える 2

2

わかりました、何が起こっていると思うかを説明します。強調しておきますが、これは私の推測です。私が完全に間違っている可能性があります。

まず、@Transactional注釈の Propagation を指定する必要はありませんでした。Required は適切な標準です。例外が発生する場合は、通常、データベースを正しく操作していないことが原因です。ただし、これまでに複数のセッション ファクトリを使用する必要がなかったため、ここではそうではない可能性があります。

SUPPORTS または NOT_SUPPORTED を指定したときに発生していると思うのは、保存が非トランザクションで行われているということです。保存が非トランザクションで行われているという理由だけで、特定のタイプのエラーが発生した場合、セッション全体が発生しないという意味ではありません。それが明らかに起こっていることなので、ロールバックします。

REQUIRED または REQUIRES_NEW を使用すると、それぞれに独自の JDBC 接続 (明らかに) を持つ新しいトランザクションが作成されますが、同じトランザクション セッションが使用されます。そのため、illegal attempt例外が発生しています。セッションは 2 フェーズ リソース用に作成されましたtransactionalが、同じセッションを使用して 1 フェーズ データベースに保存しようとしています。

@Transactional伝播は、次のように一方が他方を呼び出すアノテーションが付けられた 2 つのメソッドがある場合にのみ有効になります。

@Transactional
public void method1(){
    method2();
}

@Transactional
public void method2(){
    //do some transactional stuff here
}

メソッド 1 の新しいセッションを作成するか、既存のセッションをメソッド 2 に使用するか、メソッド 2 に新しいセッションを作成するか、またはすべてを非トランザクションで実行するかは、伝播レベルによって決まります。

于 2014-05-06T04:12:31.977 に答える
0

JTA2 フェーズ コミット トランザクションのみをサポートします。を使用しているかどうかを確認してくださいJtaTransactionManager

使用する場合、NOT_SUPPORTEDまたはSUPPORTS非トランザクションで動作するため、正常に動作します。org.springframework.transaction.annotation.Propagationjavadocを参照してください。

于 2015-10-03T18:25:24.720 に答える