Grails在成功的服务调用后不会提交
我在2.4.4中的单个Grails在成功的服务调用后不会提交,grails,gorm,transactional,Grails,Gorm,Transactional,我在2.4.4中的单个服务上执行以下逻辑 类示例服务{ 作废流程(参数1、参数2){ SampleDomain1 sd1=新的SampleDomain1() sd1.setProperties(参数1) sd1.save() SampleDomain2 sd2=新的SampleDomain2() sd2.setProperties(参数2) sd2.save() } } 我的理解是,服务s在默认情况下是事务性的。如果sd1.save()成功,但sd2.save()未成功,它将回滚更改并抛出错误
服务上执行以下逻辑
类示例服务{
作废流程(参数1、参数2){
SampleDomain1 sd1=新的SampleDomain1()
sd1.setProperties(参数1)
sd1.save()
SampleDomain2 sd2=新的SampleDomain2()
sd2.setProperties(参数2)
sd2.save()
}
}
我的理解是,服务
s在默认情况下是事务性的。如果sd1.save()
成功,但sd2.save()
未成功,它将回滚更改并抛出错误。而如果两者都成功,则在服务退出时提交
如果我的理解是正确的,那么这两个数据都应该被持久化到数据库中。但是,问题是:它没有-除非根据我使用同一组params1
和params2
的测试显式使用flush:true
参数
sd1.save(刷新:true)
SampleDomain2 sd2=新的SampleDomain2()
sd2.setProperties(参数2)
sd2.保存(刷新:真)
}
顺便说一句,这正是我真正要避免的(将其设置为@Transactional
)的意义所在。如果这就是Hibernate 4/Grails 2.4的特点,我需要做什么才能使我的服务在服务调用的每一个结尾再次提交?我需要配置Grails的任何全局配置吗?我真的需要在每次服务结束时自动刷新我的域类
注
我已经保证数据是正确的,包括调用.validate()
和其他检查器。成功执行.save(flush:true)
证明了这一点。我发现的问题是它的刷新模式
。现在,也许我真正需要的是一个全局设置来覆盖它。如果您的数据没有被刷新到数据库层,我会想到一些可能性
尝试保存到数据库时出现某种错误,您可以尝试将failOnError=true参数传递给.save()调用以清楚地看到它。(实际上,全局设置这是一个好主意,因为无声地失败db调用是一种偏头痛)
您正在从同一服务对象中调用此服务方法。由于使用代理,这将不允许底层spring声明性事务工作
您可能已经在同一服务中注释了其他方法,在这种情况下,默认事务支持不再适用于剩余的未注释(这是一个单词吗?)方法
您可能已经在服务文件夹外的某个位置创建了该服务,不太确定这是否会导致问题,因为我从未尝试过
你没有把一只山羊献给Groovy和Grails的神,他们正在搞乱你的脑袋
编辑:
我将尝试回答你新编辑中的要点
你试过failOnError吗?当两个对象同时刷新到DB中,而不是一次手动提交一个对象时,可能会出现问题
通过找出一种在保存时自动刷新的方法,您将完全绕过这些事务。好吧,如果我错了,那么请尽一切努力。但是在假设之前先测试一下
如果您的数据没有被刷新到数据库层,那么您会想到一些可能性
尝试保存到数据库时出现某种错误,您可以尝试将failOnError=true参数传递给.save()调用以清楚地看到它。(实际上,全局设置这是一个好主意,因为无声地失败db调用是一种偏头痛)
您正在从同一服务对象中调用此服务方法。由于使用代理,这将不允许底层spring声明性事务工作
您可能已经在同一服务中注释了其他方法,在这种情况下,默认事务支持不再适用于剩余的未注释(这是一个单词吗?)方法
您可能已经在服务文件夹外的某个位置创建了该服务,不太确定这是否会导致问题,因为我从未尝试过
你没有把一只山羊献给Groovy和Grails的神,他们正在搞乱你的脑袋
编辑:
我将尝试回答你新编辑中的要点
你试过failOnError吗?当两个对象同时刷新到DB中,而不是一次手动提交一个对象时,可能会出现问题
通过找出一种在保存时自动刷新的方法,您将完全绕过这些事务。好吧,如果我错了,那么请尽一切努力。但是在假设之前先测试一下
在我的DataSource.groovy
配置中,有一行:
hibernate {
...
singleSession = true // configure OSIV singleSession mode
flush.mode = 'manual' // OSIV session flush mode outside of transactional context
^^^^^^^^^^
}
其中明确说明应手动刷新每个存储。作为解决方案,我将这一行注释掉。此后,每次数据库事务在我的数据源上的某个地方存在服务时,都会提交它。groovy
配置中有以下行:
hibernate {
...
singleSession = true // configure OSIV singleSession mode
flush.mode = 'manual' // OSIV session flush mode outside of transactional context
^^^^^^^^^^
}
其中明确说明应手动刷新每个存储。作为解决方案,我将这一行注释掉。在此之后,现在每个数据库事务在每次存在服务时都会提交尝试将以下内容添加到grails.gorm.failOnError=true
到Config.groovy
中。这将告诉Grails在GORM持久性发生错误时全局抛出异常。此外,刷新Hibernate会话(即使用内存中的对象更新数据库)与提交事务不同。因此,即使在刷新之后,事务回滚也会恢复数据库更改。此外,我发现做