0

私がサービスでやっていることは大まかに次のとおりです。

runAsync 
{
  <some work here>
  myDomainObject.merge()     
}

「スレッドにバインドされた Hibernate セッションがありません。構成では、ここで非トランザクション セッションを作成することはできません」というエラーが表示されます。コードが非同期で実行されていることは確かなので、Executor プラグインが正しくセットアップされているように見えます。

次に、ドメインオブジェクト「myDomainObject」をこのスレッドにバインドしてはいけないと考えて、実行プラグインのおかげでスレッドには休止状態のセッションがあります。

runAsync
{
  <work>
  def instance2= MyDomainObject.get(myDomainObject.id) // works
  instance2.field1=123
  instance2.save() // fails
}

ここでも同じエラーが発生しますが、興味深いことに、get() は正しいデータを取得して instance2 に設定することに成功しています。失敗するのは「save()」だけです。これは、デバッガーでコードをステップ実行したことがあるからです。

最後に、次のようにすると、すべてが機能します。

runAsync 
    {
      <some work here>
      MyDomainObject.withTransaction {
           myDomainObject.field1=123
           myDomainObject.merge()
      }
    }

上記のコードを記述しているサービスをトランザクション対応に設定していないため、このトランザクションが必要な理由がわかりません。ここで私が知らない基本的な何かがあるに違いないことは知っていますが、それが何であるかを見つけることはできません。

4

1 に答える 1

2

あなた自身の質問に答えたようです:)

上記のコードを書いているサービスを transactional に設定していないため、このトランザクションが必要な理由がわかりません。

NOTE ON TRANSACTIONSをご覧ください。サービスはトランザクション対応である必要があります。

トランザクションに関する注意: これは新しいスレッドをスピンオフすることであり、すべての呼び出しは現在のトランザクションの外部にあることに注意してください。クロージャ内で .withTransaction を使用して、runnable または callable ではないトランザクションでプロセスを実行させます。トランザクションサービス メソッドの呼び出し (コントローラーで this を使用する場合など)。

更新
以下のようなサービスクラスを試してください:

class MyService{

    def someMethod(){
        runAsync {
            anotherMethod()
        }
    }

    def anotherMethod(){ 
       <work>
       def instance2= MyDomainObject.get(myDomainObject.id) // works
       instance2.field1=123
       instance2.save() // should work as well
    }
}
于 2013-10-06T15:26:00.850 に答える