0

Oracle 11g と一緒に grails 1.3.7 を使用し、内部トランザクションを管理しようとしています。いくつかの変更を行うトランザクション(Propagation.REQUIRED)サービス メソッドに渡される Bean Person があります。次に、別のトランザクション(propagation = Propagation.REQUIRES_NEW)メソッドに渡され、別の変更が加えられて例外がスローされます。私が期待していたのは、2 番目のサービスのすべての変更がロールバックされることですが、最初のサービスの変更はまだ有効です。これは状況です:

//outer transaction
class MyService {

    def nestedService

    @Transactional(propagation = Propagation.REQUIRED)
    public void testRequiredWithError(Person person) {
        person.name = 'Mark'
        try {
            nestedService.testRequiresNewWithError(person)
        } catch (RuntimeException e) {
            println person.age //this prints 15
            println e
        }
    }
}//end MyService

//inner transaction
class NestedService{

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void testRequiresNewWithError(Person person) {
        person.age = 15 //expected after Exception will be discarded
        throw new RuntimeException("Rollback this transaction!")
    }
}

次に、grails コンソールを実行し、終了後に DB を確認します。...

 def p = Person.get(671)
    def myService = ctx.myService 

    println p.name //'John'...from DB
    println p.age  //25...from DB

    myService .testRequiredWithError(p)

    println p.name // 'Mark'....correct
    println p.age  //  15....UNEXPECTED..
    //same result checking on the DB after console ends and transaction flushes

Propagation.NESTED をブートストラップでアクティブ化した後transactionManager.setNestedTransactionAllowed(true)、このポスト grails トランザクション セット セーブポイントのようにセーブポイントを使用して使用しようとしました が、それでも同じ結果が得られました。

何が欠けていますか????

前もって感謝します。

4

2 に答える 2

1

パーティーに少し遅れましたが、答えが見つからない場合は、トランザクションで問題が発生している理由を知っていると思います.

セーブポイントに関する問題についてのディスカッションへのリンクを見ました。その議論によると、MySQL をデータソースとして使用しています。MySQL はデフォルトではトランザクションをサポートしていません。そうするには、特別な方法でテーブルを作成する必要があります。トランザクションを使用する場合に MySQL でテーブルを作成する方法を説明する以下のリンクを提供しました。

http://www.tutorialspoint.com/mysql/mysql-transactions.htm

編集: この記事では、トランザクションをサポートするために、テーブルのタイプを InnoDB に設定することをお勧めします。以下に例を示します。

mysql> create table tcount_tbl
    -> (
    -> tutorial_author varchar(40) NOT NULL,
    -> tutorial_count  INT
    -> ) TYPE=InnoDB;

これがトランザクションをサポートする唯一のタイプではなく、最も一般的なタイプであることに注意してください。MySQL 5.5 以降では、タイプ InnoDB としてテーブルを自動的に作成する必要があります。

お役に立てれば!

于 2016-05-17T13:04:46.087 に答える
0

p.isAttached()トランザクションのロールバックが Hibernate セッションからドメイン オブジェクトを切り離すのをテストします。また、テストでは、データベースからドメイン オブジェクトをリロードします。事実上、データベースp = Person.get(671)からデータをリロードします。

ageテスト後にプロパティが 15 に設定されている理由は、例外の後、ドメイン オブジェクトとデータベースが同期していない (そしてドメイン オブジェクトが切り離されている) ためだと思います。

詳細については、https ://weblogs.java.net/blog/blog/davidvc/archive2007/04/jpa_and_rollbac.html を参照してください。

于 2015-08-04T12:19:57.227 に答える