Hibernate 使用GrailsExector插件';s runAsync,为什么需要事务来保存域对象?

Hibernate 使用GrailsExector插件';s runAsync,为什么需要事务来保存域对象?,hibernate,grails,transactions,gorm,executor,Hibernate,Grails,Transactions,Gorm,Executor,以下是我在服务中的大致操作: runAsync { <some work here> myDomainObject.merge() } runAsync { myDomainObject.merge() } 我得到一个错误,说“没有绑定到线程的Hibernate会话,配置不允许在这里创建非事务会话”。我确信代码是异步运行的,所以执行器插件的设置似乎是正确的 因此,我下一步尝试了这个方法,认为域对象“myDomainObject”不能绑定在此线程中,尽管由于ex

以下是我在服务中的大致操作:

runAsync 
{
  <some work here>
  myDomainObject.merge()     
}
runAsync
{
myDomainObject.merge()
}
我得到一个错误,说“没有绑定到线程的Hibernate会话,配置不允许在这里创建非事务会话”。我确信代码是异步运行的,所以执行器插件的设置似乎是正确的

因此,我下一步尝试了这个方法,认为域对象“myDomainObject”不能绑定在此线程中,尽管由于executor插件,线程有一个hibernate会话:

runAsync
{
  <work>
  def instance2= MyDomainObject.get(myDomainObject.id) // works
  instance2.field1=123
  instance2.save() // fails
}
runAsync
{
def instance2=MyDomainObject.get(MyDomainObject.id)//works
instance2.field1=123
instance2.save()//失败
}
我在这里得到了同样的错误,有趣的是,get()成功地带来了正确的数据并将其设置为instance2。只有“save()”失败了。我之所以知道这一点,是因为我已经在调试器中逐步完成了代码

最后,如果我执行以下操作,一切正常:

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

我不明白为什么需要这个事务,因为我还没有将我正在编写上述代码的服务设置为事务性的。我知道这里一定有一些基本的东西我不知道,但我不知道它是什么。

看起来你回答了你自己的问题:)

我不明白为什么需要这个事务,因为我没有将我正在编写上述代码的服务设置为事务性的

看一看这张照片。你需要你的服务是事务性的

关于事务的注意事项:请记住,这是从一个新的 线程,并且任何调用都将在您正在处理的事务之外 在里面在闭包内使用.withTransaction,可运行或可调用 使您的进程在不调用 事务性服务方法(例如在 控制器)

更新
尝试如下所示的服务类:

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
    }
}
classmyservice{
def someMethod(){
运行异步{
anotherMethod()
}
}
def anotherMethod(){
def instance2=MyDomainObject.get(MyDomainObject.id)//works
instance2.field1=123
instance2.save()//也应该可以工作
}
}

所以这里有一部分我不明白:“任何呼叫都将在您所在的交易之外。”我不认为我在交易中。还是Grails中的所有服务都是自动事务?是的,Grails中的所有服务在默认情况下都是事务性的,除非您指定
static transactional=false
。查看我的更新@Triarc感谢您澄清服务的性质@dmahapatro。然而,我看不出我在第二次尝试中所做的(如我上面的帖子所示)与您在更新中所做的有什么区别。为了简单起见,我展示的代码去掉了anotherMethod(),但这正是我在代码中所做的,我得到了相同的错误。在这种情况下,为什么使用另一种方法会有所帮助?谢谢@您的服务是事务性的吗?您是否在其任何方法上使用了
@Transactional