Grails在成功的服务调用后不会提交

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()未成功,它将回滚更改并抛出错误

我在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()
未成功,它将回滚更改并抛出错误。而如果两者都成功,则在服务退出时提交

如果我的理解是正确的,那么这两个数据都应该被持久化到数据库中。但是,问题是:它没有-除非根据我使用同一组
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会话(即使用内存中的对象更新数据库)与提交事务不同。因此,即使在刷新之后,事务回滚也会恢复数据库更改。此外,我发现做