1

まず、JPA2の実装としてSpring+Hibernateを使用していることに注意してください。私のアプリケーションは、JpaTransactionManagerとHibernateJpaDialectで構成されています。

ユニットを非アクティブ化する機能と、複数のユニットの非アクティブ化をラップする機能があります。ユニットの非アクティブ化作業は外部サービスを呼び出し、その呼び出しがタイムアウトするか、エラーステータスで戻ると、例外がスローされます。単一ユニットの非アクティブ化が失敗した場合(この外部サービス呼び出しを介して、またはRuntimeExceptionが原因で)、そのユニットのトランザクションのみをロールバックしたいと思います。

Propogation.REQUIRES_NEWを使用して、基本的に以下のようにこれを実現できます。

@Transactional
public void deactivateUnits(List<String> names){
    for(String name : names){
        deactivateUnit(name);
    }
}
@Transactional(propogation=Propogation.REQUIRES_NEW, rollbackFor=MyException.class)
public void deactivateUnit(String name) throws MyException{
    ..snip..
    //Some code that throws MyExceptions or RuntimeExceptions
    ..snip..
}

そして、これは完全にうまく機能します。

このスタイルは、アクティベーションにも非常によく拡張されます。

@Transactional
public void activateUnits(List<String> names){
    for(String name : names){
        activateUnit(name);
    }
}
@Transactional(propogation=Propogation.REQUIRES_NEW, rollbackFor=MyException.class)
public void activateUnit(String name) throws MyException{
    ..snip..
    //Some code that throws MyExceptions or RuntimeExceptions
    ..snip..
}

しかし、やるときになると問題にreactivationぶつかります。私が欲しいのは、既存の関数と関数reactivationを利用するアトミックタスクです。つまり、またはのいずれかがロールバックを引き起こした場合、関数全体がロールバックします。deactivateUnitactivateUnitdeactivateUnitactivateUnit

これに対する私の素朴な試みはうまくいきません:

@Transactional(propogation=Propogation.REQUIRES_NEW, rollbackFor=MyException.class)
public void reactivateUnit(String newName, String oldName) throws MyException{
    deactivateUnit(oldName);
    activateUnit(newName);
}

activateUnitロールバックする場合は、deactivateUnitしません。

アクティブ化と非アクティブ化の伝播をに変更する必要があるかもしれないと思いましたが、それではNESTED関数のロールバック動作が維持されません。

少し戸惑っていますので、よろしくお願いします!

4

1 に答える 1

0

この場合、最初に注釈が付けられた activateUnit 関数を利用できるとは思いません。REQUIRES_NEW でラッパー関数を使用して、注釈のないヘルパー関数を呼び出す必要がある場合があります。次に、reactivateUnit メソッドでヘルパー関数も呼び出します。

于 2012-01-30T15:21:19.253 に答える