Leandro Roura Sixto
Leandro Roura Sixto

Reputation: 712

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

I have a method written in a Grails service, which processes a lot of data.
I noticed that, sometimes, the method returns success but the data is not persisted to the database.

I debugged it, following all the data till the end of the method and everything is fine, however data is not persisted.

The following image demonstrates the what I just explained. You can see the end of the method, in which a Map object is filled with persistent object metadata. Even you can see the console which contains the printend Hibertate SQL

Debugging

How can I detect whether a rollback mechanism is thrown after successful method returning?

This is my connection properties for Oracle 12c database. Others configurations are Grails defaults

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>

The service is anotated as @Transactional

@Transactional
class SincronizacionService {

}

Any Idea?

Upvotes: 2

Views: 265

Answers (3)

Leandro Roura Sixto
Leandro Roura Sixto

Reputation: 712

I found the problem. In this method actaDenunciaService.generarActaDenuncia(denuncia), there is a peculiarity. In a part of the method is located the following snippet:

            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))
            }

A team member changed this line nomencladorService.obtenerNomencladorDNomenclador(meta.valor.toLong()). The change represented a huge improvement of memory saving. However, the team member did not take into account a business process, which does not take into account the method he used.

Yes, a runtime exception is being thrown.

And the treatment, depending on the objective of the method, is correct

For the future, this is how the method will be from now on:

            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()) for the business process
  • e.printStackTrace() for tracing any other peculiarity

Thanks a lot to everybody who had collaborated on finding this error

Upvotes: 2

Leandro Roura Sixto
Leandro Roura Sixto

Reputation: 712

I found the error!

An error thrown inside a method for generating a PDF document with data, appearsto be failing. The second line shows this

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

Now, the new question is: If the method is encapsulated inside a try/catchblock, why the catch block is not excecuting?

When I comment the 2nd line inside try/catch block, data is persisted on database

With no comments, generation PDF method is executed till the end, doing all what it must do

Upvotes: 1

elixir
elixir

Reputation: 1442

When using GORM's save method, also use failOnError:true. By default, save method silently fails. However, if you use failOnError:true, it will throw an exception if the data is not persisted.

If you do not want to stop the program when the data fails to save, you can use the try-catch block to log data that failed to save and let the algorithm continue to do it work.

Hope that helps.

Upvotes: 2

Related Questions