6

Spring は、TX 管理をきめ細かく制御できるプログラムによるトランザクションをサポートしています。Spring Documentation によると、次の方法でプログラムによる TX 管理を使用できます
。 1. Spring の TransactionTemplate を利用する:

transactionTemplate.execute(new TransactionCallbackWithoutResult() {

protected void doInTransactionWithoutResult(TransactionStatus status) {
    try {
        updateOperation1();
        updateOperation2();
    } catch (SomeBusinessExeption ex) {
        status.setRollbackOnly();
    }
} });

2. PlatformTransactionManager を直接活用する (DAO に PlatformTransactionManager 実装を挿入する):

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

//txManager is a reference to PlatformTransactionManager
TransactionStatus status = txManager.getTransaction(def);
try {
  updateOperation1();
  updateOperation2();
}
catch (MyException ex) {
    txManager.rollback(status);
    throw ex;
}
txManager.commit(status);

簡単にするために、JDBC データベース操作を扱っているとしましょう。

updateOperation1(),updateOperation2()2番目のスニペットでデータベース操作が発生したかどうか疑問に思っています。実装されているJDBCTemplateJDBCDaoSupport、そうでない場合、操作は実際にはトランザクション内で実行されませんか?

JDBCTemplate私の分析では、またはを使用しない場合JDBCDaoSupport、必然的にデータソース管理から接続を作成/取得することになります。もちろん、取得する接続は、PlatformTransactionManagerトランザクションを管理するために基盤となるものが使用する接続ではありません。

私はSpringのソースコードを掘り起こし、スキム関連のクラスがPlatformTransactionManager見つかっConnectionHolderTransactionSynchronizationManager. 私も見つけJDBCTemplateJDBCDaoSupport,、同様のルーチンとの接続を取得しようとしましたTransactionSynchronizationManager.

スレッドごとの接続を含む多くのリソースを管理するためTransactionSynchronizationManager(基本的にはThreadlocal、1 つのスレッドが管理対象リソースの固有のインスタンスを確実に取得するために使用します)

JDBCTemplateしたがって、 PlatformTransactionManager によって取得された接続はまったく同じであると思いますJDBCDaoSupport。これは、春のプログラムによるトランザクションがトランザクションによってどのようupdateOperation1(),updateOperation2()に保護されたかを説明できます。

私の分析は正しいですか?そうである場合、Spring のドキュメントでこの警告が強調されていないのはなぜですか?

4

1 に答える 1

4

はい、正しいです。

raw を使用するすべてのコードは、Spring によって管理されるトランザクションに参加するために特別な方法でConnectionそれらを取得する必要があります( 12.3.8 DataSourceTransactionManager ):DataSource

Java EE の標準 DataSource.getConnection ではなく、DataSourceUtils.getConnection(DataSource) を介して JDBC 接続を取得するには、アプリケーション コードが必要です。

別のオプション ( を呼び出すコードを変更できない場合getConnection()) は、 でラップするDataSourceことTransactionAwareDataSourceProxyです。

于 2012-06-18T17:42:55.737 に答える