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
?