1

Spring でのトランザクションの処理に問題があります。私は単純に一定回数反復する Web サービスを持っており、そのたびに Oracle データベースにレコードを挿入します。サービスの挿入メソッドを @Transactional としてマークしました。これは、挿入が失敗したとき (RuntimeException の後、つまり、null オブジェクトが挿入された場合) にロールバックするようにするためです。

問題は、Spring アプリケーション コンテキストを介してサービスをインスタンス化するメインを使用して Java でサービスをテストすると、すべてが正常に機能することです (すべてのレコードがロールバックされます)。代わりに、ローカル サーバーにデプロイした後、soapUI を使用して Web サービスをテストすると、@Transactional アノテーションが表示されないようになります。

コードを報告します。

これが私のサービスです:

@Service
public class MyService{

        @Transactional
        public void insert(List<DAO> l) {

              for(DAO item : l) {
              //Insert item into the DB
              //and throw a RunTimeException in case of failure (i.e.,item null)
              }
        }
}

これが私のメインです:

public class TestMain{

    public static void main(String[] args) {

        ApplicationContext ac = new FileSystemXmlApplicationContext(SPRING_CONTEXT_XML_PATH);

        MyService service = ac.getBean(MyService .class);

        List<DAO> l; //Suppose it is initialized    
        service.insert(l); //Rollback working if RuntimeException is thrown     
}

}

前述のように、Spring アプリケーション コンテキストを使用して Web サービスをインスタンス化すると、上記のコードは機能しますが、サーバーにデプロイした後に soapUI を介して MyService を呼び出すと (これが実際にサービスの目的です)、@Transactional は機能しません。実行されました。

誰かが私にこの振る舞いを説明できますか?

どうもありがとうございました。

4

1 に答える 1

0

spring はアノテーションinsertを持っているため、メソッドが呼び出されるたびにトランザクションを開始します。返されると、トランザクションはコミットされます (例外がスローされた場合はロールバックされます) @Transactionalinsert

spring が type の Bean を作成するとき、メソッドを次のようMyServiceにラップします。insert

EntityManager em = ...; // get EntityManager here
EntityTransaction tx = null;
try {
    tx = em.getTransaction();
    tx.begin();

    // your insert method is called here.

    tx.commit();
} catch (Exception e) {
    if ( tx != null && tx.isActive() ) {
        tx.rollback();
    }
}

soupUI は@Transactionalアノテーションを処理しません。トランザクションを開始し、自分でコミット/ロールバックする必要があります。

于 2012-11-14T11:02:12.600 に答える