2

次のコード スニペットを参照してください。

@Transactional
public void saveMembersService(List<Member> list1, List<Member> list2)
{
    saveMembersDAO(list1); // does not perform commit. Why?
    saveMembersDAO(list2); // does not perform commit. Why?
} // does perform commit only here!

@PersistenceContext
private EntityManager em;

@Transactional
public void saveMembersDAO(List<Member> members)
    throws HibernateException
{
    Iterator<Member> it = members.iterator();
    while (it.hasNext())
    {
        Member wsBean = it.next();
        em.persist(wsBean); // overall commit will be made after method exit
    }
}

MySQLをDBとして使用しています。上記のメソッドの実行後、MySql ログを監視します。しかし、 saveMembersServiceメソッドの実行後に単一のコミットしか表示されません。トランザクション メソッドの呼び出しごとに2 つのコミットが見られると予想しています。どこが間違っていますか?

更新 1:申し訳ありませんが、サービス メソッドに @Transactional を追加するのを忘れていました。今直った

更新 2: DAO のPropagation.REQUIRES_NEW属性で確認しました- 結果は同じです (@Transactional at service メソッドの有無にかかわらず)

4

1 に答える 1

3

@Transactionalを使用すると、Springはクラスの周囲にプロキシを作成し、内部で呼び出されたメソッドはプロキシを渡しません。

代わりにこれを行う必要があります。SpringコンテキストでTransactionTemplateを作成することでクリーンアップできます。

@Autowired
private PlatformTransactionManager transactionManager;

public void saveMembersDAO(List<Member> members)
    throws HibernateException
{
    TransactionDefinition txDef = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    TransactionTemplate txTemplate = new TransactionTemplate(transactionManager, trDef)

    txTemplate.execute(new TransactionCallbackWithoutResult() {

        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            Iterator<Member> it = members.iterator();
            while (it.hasNext())
            {
                Member wsBean = it.next();
                em.persist(wsBean);
            }
        }
    });
}

AspectJを使用していて、2つのコミットが必要な場合。saveMembersDAOで@Transactional(propagation = Propagation.REQUIRES_NEW)を使用する必要があります

于 2012-10-16T19:05:10.567 に答える