如何知道方法返回后数据库事务期间数据是否持久化?

How to know if data was persisted during database transaction after method returning?

我有一个用 Grails 服务编写的方法,它处理大量数据。
我注意到,有时,方法 returns 成功,但数据并未持久保存到数据库中。

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

下图演示了我刚才解释的内容。您可以看到该方法的结尾,其中 Map 对象填充了持久对象元数据。即使你可以看到包含 printend Hibertate SQL

的控制台

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

这是我的 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 {

}

有什么想法吗?

使用GORM的保存方法时,也使用failOnError:true。默认情况下,保存方法静默失败。但是如果使用failOnError:true,数据没有持久化就会抛出异常

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

希望对您有所帮助。

我发现错误了!

生成带有数据的 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方法执行到最后,该做的都做了

我发现了问题。在这个方法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())。这一变化代表了内存节省的巨大改进。但是,这个团队成员没有考虑到一个业务流程,没有考虑到他使用的方法。

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

并且根据方法的objective进行处理,是正确的

以后的方法是这样的:

            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() 用于追踪任何其他特性

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