1

注釈が付けられ@Transactionalた(したがってトランザクションを開始する)メソッドがどこかにあり、内部でいくつかのsaveAndFlush(). たぶん、アノテーションを付けることで独自の(サブ?ネストされた?)トランザクションを開始するメソッドを持つ依存関係を呼び出すことさえあります@Transactional。トランザクションが途中で失敗した場合、何がロールバックされますか?

いくつかの例:

public class ComplexProcess {
    @Inject
    private DAO<SomeEntity> someEntityDao;

    @Inject
    private SomeManagerClass manager;

    @Transactional
    public void doStuff(SomeEntity entity) {
        manager.createAnObjectDependingOnEntity(entity);
        entity = someEntityDao.saveAndFlush(entity); // what if this fails?
        manager.doMoreStuffDependingOnEntity(entity);
    }
}

public class SomeManagerClass {

    @Inject
    private DAO<SomeObject> someObjectDao;

    @Inject
    private DAO<SomeOtherEntity> someOtherEntityDao;

    // what if this fails?
    @Transactional // what if this isn't there?
    public void createAnObjectDependingOnEntity(SomeEntity entity) {
        SomeObject someObject = createSomeObjectDependingOnEntity(entity);
        someObjectDao.saveAndFlush(someObject);
    }

    // what if this fails?
    @Transactional // what if this isn't there?
    public void doMoreStuffDependingOnEntity(SomeEntity entity) {
        SomeOtherEntity someOtherEntity = whatever(entity);
        someOtherEntityDao.safeAndFlush(someOtherEntity);
    }
}

繰り返しますが、最後のステップが失敗したとしたら、休止状態は以前に発生したすべてをロールバックしdoStuff()ますか? そうではないという感覚があるからです。が原因でこの完全なロールバックが不可能な場合、トランザクションの最後に自動フラッシュをsaveAndFlush()使用して待機するだけで解決しますか? ブロックsave()を離れる前でも、休止状態が制御不能なフラッシュを独自に実行することを読んだところですか?!@Transactional

4

2 に答える 2

9
  • フラッシュは、トランザクション管理にまったく影響を与えるべきではありません。トランザクションがロールバックされると、そのトランザクション内でデータベースの状態に加えられたすべての変更 (つまり、Hibernate によってフラッシュされた変更) がロールバックされます。

  • のデフォルトの伝播ポリシーは@TransactionalですPROPAGATION_REQUIRED@Transactionalこれは、他のメソッドからメソッドを安全に呼び出すことができ@Transactional、最上位のトランザクション メソッドによって作成された同じトランザクションを使用することを意味します。異なる伝播設定を明示的に提供する場合はそうではありません。

つまり、トップ レベル@Transactionalメソッドの実行中に発生した障害 (つまり、そのメソッドからスローされた例外) によってロールバックが発生し、この場合、すべての変更がロールバックされる必要があることを意味します。

異なる動作が見られる場合は、何かが正しく構成されていない可能性があります (たとえば、トップ レベル@Transactionalが何らかの理由で有効になっていないなど)。テストでこの動作を再現してみてください。

于 2013-11-05T11:08:45.600 に答える
1

あなたのコードでは、現在のトランザクションをロールバックすることがどこかで決定された場合、Hibernate が行ったすべての変更をロールバックする必要があります。もちろん、すべてが正しく構成されている場合に限ります。

いくつかの一般的な構成の問題は次のとおりです。(の代わりに) 永続化ユニットpersistence.xmlを定義する必要があり、データベース/テーブルはトランザクションをサポートする必要があります (たとえば、MySQL テーブルは InnoDb 検索エンジンを使用する必要があります)。JTARESOURCE_LOCAL

于 2013-11-05T11:10:54.143 に答える