2013-02-22 16 views
15

SpringのPlatformTransactionManagerを使用してトランザクションのコミットとロールバックを手動で実行したため、トランザクション後にコミット後のアクションが発生するようにフックを設定しますコミット。見ることによってSpringでトランザクションを使用するときのコミットの作成

:私はトランザクションを決定する方法を見て傾ける

void commit(TransactionStatus status) throws TransactionException; 

にはexpceptionがスローされていないので、もしそれをassumming以外成功しました。

私は1つのオプションとしてAOPを使うことができましたが、programmitcallyはコールバックメソッドを使用していましたか?

答えて

33

あなたはTransactionSynchronizationManagerTransactionSynchronizationで、簡単な方法で正確にあなたが欲しいものを得ることができます

TransactionSynchronizationManagerは、現在のトランザクションに関する情報を取得するための静的メソッドを持っている、とあなたはTransactionSynchronizationウィッヒはあなたが自動的に行うことができます登録することができますコミット後のあなたは

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization(){ 
      void afterCommit(){ 
       //do what you want to do after commit 
      } 
}) 

がTransactionSynchronizationがパーであることに注意していることを呼び出すとスレッドベース(基本的なWebリクエストでは問題にならないことが多い)。

+0

これはかなりいいと思われます...そのような単一のスレッドにバインドされ、呼び出しが再帰的である場合...1つのスレッドがトランザクションを開始すると、同期が登録され(1 - コミット後)、そのトランザクションに参加する別のメソッドを呼び出して同期を登録します(2 - コミット後)....コミットすると...コミット・シンクロナイザそれらが1つのセットに格納されているために解雇されるでしょうか?多分私は間違ってテストしなければなりません... – user1555190

+0

'TransactionSynchronization'オブジェクトは' TransactionSynchronizationManager 'で取り出すことができるスレッドリストによってリストとして保持されます。 getSynchronizations() ' – Grooveek

+0

私はそれがセットとして保持されていると信じて、リストとして返されます... Set synchs .............. return new ArrayList (synchs) .....コミットした後に二人がコミットしたと思っているだけです。 – user1555190

1

私のプロジェクトの中には、理由があるので、PlatformTransactionManagerも使用しなければならなかった。だから、私は強制的にorg.springframework.transaction.support.TransactionTemplateを使用しました。

http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/transaction/support/TransactionTemplate.html

主な利点は、あなたが正しくPlatformTransactionManagerを実装している場合、あなたがコミット/ロールバックのマニュアルを気にする必要はないということです。より具体的なことが必要な場合は、少なくともTransactionTemplateのソースコードが役に立ちます。

それは使用することをかなり単純です:

config.xmlの

<bean name="transactionTemplate" 
      class="org.springframework.transaction.support.TransactionTemplate"> 
    <property name="transactionManager" ref="platformTransactionManager"/> 
</bean> 

MyServiceImpl.java

 

@Service 
public class MyServiceImpl implements MyService { 

    @Autowired 
    private TransactionTemplate transactionTemplate; 

    public Entity getSomethingWithTx(final long id) { 

     return transactionTemplate.execute(new TransactionCallback<Entity>() { 
      @Override 
      public Entity doInTransaction(TransactionStatus status) { 
       //TODO implement 
      } 
     }); 
    } 

+0

厥は本当に物事を手動でコーディング側で役立ちますが、それはどのように取引天気を伝えることが可能である:あなたが@Transactional法上のコールバックを必要とする場合、それは成功したばかりの方法の初めにそれを追加をコミットした後、ロールバックまたは正常にコミットされ、私はstatus.iscompleted()を見ることができます..しかし、それは成功したロールバックまたは成功したコミットを意味する可能性があります...? – user1555190

+1

トランザクションは2つの場合のみロールバックされます。コールバックコードはdoInTransactionを終了する例外をスローするか、暗黙的なロールバック呼び出しがあります(これは強く推奨されず、おそらくUnexpectedRollbackExceptionを生成します)。したがって、getSomethingWithTxが例外をスローしなかった場合、トランザクションが正常にコミットされたと見なすことができます。 – mrembisz

6

グルーベックの答えとアレックスのコメントの賛同を表明しました。これは、ネットの周りでは見つけにくい、しっかりとしたクリーンなソリューションを提供するためです。

Spring 4+を使用する。

@Service 
public class OneService { 

    @Autowired 
    OneDao dao; 

    @Transactional 
    public void a transactionalMethod() { 
     TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){ 
      public void afterCommit(){ 
       //do stuff right after commit 
       System.out.println("commit!!!"); 

      } 
     }); 
     //do db stuff 
     dao.save(); 
    } 
} 
+1

彼の答えのために@Michailに感謝します。トランザクションロールバックの場合、このアプローチは「afterCompletion(int status)」を使用し、status == TransactionSynchronizationをチェックすることで機能します。 STATUS_ROLLED_BACK – deep

関連する問題