Hibernate 跨语言只读=真&;在Grails和Postgres中保存对象

Hibernate 跨语言只读=真&;在Grails和Postgres中保存对象,hibernate,spring,postgresql,grails,Hibernate,Spring,Postgresql,Grails,我们正在使用Grails[Spring+Hibernate],并且有一个带有@Transactional(readOnly=true)的服务方法。在开发和测试期间,我们使用了HSQLDB,其行为使我们可以使用.save(flush:true)和object保存到数据库中,但所有其他对象都将回滚。 当我们转到博士后,一切都很好。现在,此设置返回: 错误-事务是只读的 编辑: 我们必须能够回滚事务中的所有数据,但仍然能够保存需要保存的数据[一些与事务无关的附加内容,如用于日志记录的内容]。它不想使用

我们正在使用Grails[Spring+Hibernate],并且有一个带有@Transactional(readOnly=true)的服务方法。在开发和测试期间,我们使用了HSQLDB,其行为使我们可以使用.save(flush:true)和object保存到数据库中,但所有其他对象都将回滚。 当我们转到博士后,一切都很好。现在,此设置返回: 错误-事务是只读的

编辑:

我们必须能够回滚事务中的所有数据,但仍然能够保存需要保存的数据[一些与事务无关的附加内容,如用于日志记录的内容]。它不想使用任何DB触发器来实现这一点。我们也不希望在原始请求发出后保存内容时出现过时的对象异常。
关于我们如何实现这一目标,有什么想法吗?我唯一想到的是要有一个注册表,在那里我们可以存储对修改对象的引用,并在最后删除所有更改,但这是最后的选择。我确信有一种方法可以解决这个问题,而不必做愚蠢的事情。

我认为spring只需调用connection.setReadOnly(true),然后由jdbc驱动程序决定。也许HSQLDBJDBC只是将其作为优化某些内容的提示。对只读语义的理解是明确的:

当事务为只读时,不允许使用以下SQL命令:如果要写入的表不是临时表,则不允许使用INSERT、UPDATE、DELETE和COPY FROM命令;所有创建、更改和删除命令;评论、授予、撤销、截断;并解释分析和执行他们将执行的命令是否在列出的命令中


米兰。我和Krystian一起研究这个问题。我已经测试了所有的传播字段来解决这个问题,但没有一个有效(传播是必需的,需要新的和嵌套的,看起来值得一试)。

所以我们找到了解决方案。 在grails jira中:


谢谢米兰。但是,这不是设置为只读的Postrgres DB事务,而是Spring事务。Save应创建一个新事务,仅用于保存内容并立即提交。其他所有内容都具有自动回滚功能,因此不会将任何内容保存到数据库中。我认为您只是将此事务视为DB事务,而不是Spring事务。那么Spring显然不会为save打开新的RW事务如果显式指定REQUIRES_new作为save会发生什么情况?使用REQUIRES_new,您确定新事务不再是只读的吗?如果有必要,您可以调试、进入jdbc吗?我怀疑这是一个spring bug(以前可能有人碰到过),所以一定有一些事情你做得不好。你为什么不把代码去掉,或者更好的是,开始一个新的小项目,只暴露这个“bug”。当我尝试这一点时,我通常会在代码或设置中发现bug。如果它仍然不起作用,你可以把它放到网上,让别人看看。