如何在方法返回后知道数据库事务期间数据是否保持不变?

时间:2017-11-23 19:55:13

标签: grails transactions gorm

我有一个用Grails服务编写的方法,它处理大量数据 我注意到,有时候,该方法会返回成功,但数据不会持久存储到数据库中。

我调试它,跟踪所有数据直到方法结束,一切都很好,但数据不会持久化。

下图显示了我刚才解释的内容。您可以看到方法的结尾,其中Map对象用持久对象元数据填充。甚至你可以看到包含主页Hibertate SQL的控制台

Debugging

如何在成功返回方法后检测是否抛出了回滚机制?

这是Oracle 12c数据库的连接属性。其他配置是Grails默认值

dataSource.pooled=true
hibernate.jdbc.use_get_generated_keys=true
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=false
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
dataSource.driverClassName=oracle.jdbc.driver.OracleDriver
dataSource.dialect=org.hibernate.dialect.OracleDialect

dataSource.url=jdbc:oracle:thin:@172.16.1.20:1521:db
dataSource.username=<USER>
dataSource.password=<PASS>
hibernate.default_schema=<SCHEMA>

该服务被分配为@Transactional

@Transactional
class SincronizacionService {

}

任何想法?

3 个答案:

答案 0 :(得分:2)

使用GORM的save方法时,也使用failOnError:true。默认情况下,save方法静默失败。但是,如果使用failOnError:true,则在数据未持久化时会抛出异常。

如果您不想在数据无法保存时停止程序,可以使用try-catch块记录无法保存的数据,并让算法继续工作。

希望有所帮助。

答案 1 :(得分:2)

我发现了问题。在这种方法actaDenunciaService.generarActaDenuncia(denuncia)中,有一个特点。该方法的一部分位于以下代码段:

            try {
                DNomenclador nomenclador = nomencladorService.obtenerNomencladorDNomenclador(meta.valor.toLong())
                if (!nomenclador) {
                    return toReturn(limpiarTexto(meta.valor))
                } else {
                    return toReturn(nomenclador.valor)
                }
            } catch (Exception e) {
                return toReturn(limpiarTexto(meta.valor))
            }

团队成员更改了此行nomencladorService.obtenerNomencladorDNomenclador(meta.valor.toLong())。这一变化代表了内存节省的巨大改进。但是,团队成员没有考虑业务流程,因为业务流程没有考虑到他使用的方法。

是的,正在抛出运行时异常。

根据方法的目的,治疗是正确的

对于未来,这是该方法从现在开始的方式:

            try {
                DNomenclador nomenclador = nomencladorService.obtenerNomencladorDNomencladorLibre(meta.valor.toLong())
                if (!nomenclador) {
                    return toReturn(limpiarTexto(meta.valor))
                } else {
                    return toReturn(nomenclador.valor)
                }
            } catch (Exception e) {
                e.printStackTrace()
                return toReturn(limpiarTexto(meta.valor))
            }
  • nomencladorService.obtenerNomencladorDNomencladorLibre(meta.valor.toLong())用于业务流程
  • e.printStackTrace()用于追踪任何其他特性

非常感谢所有合作发现此错误的人

答案 2 :(得分:1)

我发现了错误!

在生成包含数据的PDF文档的方法中抛出的错误似乎失败了。第二行显示了这个

        try {
            denuncia.xmlFirmadoServ = dfileManagerService.guardarDFile(signatureResponse.resultado, "xmlfirmadoservidor.xml", usuario)
            denuncia = actaDenunciaService.generarActaDenuncia(denuncia).denuncia
        } catch (Throwable t) {
            denunciaUtilService.incrementarNumeroDenuncia(true)
            throw t
        }

现在,新的问题是:如果方法封装在try/catch块内,为什么catch块没有优先权?

当我在try/catch块内注释第二行时,数据会保留在数据库

没有评论,生成PDF方法一直执行到最后,做所有必须做的事情