olavloite / spanner-jdbc

JDBC Driver for Google Cloud Spanner
MIT License
38 stars 10 forks source link

ABORTED: Aborted due to transient fault #120

Closed ptamburro closed 5 years ago

ptamburro commented 5 years ago

We have a lot of this errors, when we save or update entities: ... Caused by: nl.topicus.jdbc.exception.CloudSpannerSQLException: ABORTED: Aborted due to transient fault\nretry_delay {\n}\n\n\tat nl.topicus.jdbc.resultset.CloudSpannerResultSet.next(CloudSpannerResultSet.java:125)\n\tat com.zaxxer.hikari.pool.HikariProxyResultSet.next(HikariProxyResultSet.java)\n\tat org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProces ...

After this error, if we repeat the action (POST/PUT) the error dooesn't happen.

Regards. Pablo.-

olavloite commented 5 years ago

This is often an indication that you are running long during transactions. You should be aware that if your jdbc connection is not in autocommit mode, the connection will begin a new transaction when you issue a query. This transaction will last until you do a commit. That means that if you do two queries a couple of minutes apart, and you do not issue a comit after each select query (or run the connection in autocommit mode), you will get very long running transactions that are very prone to these errors. This is because Cloud Spanner will abort transactions that are running for too long in order to reduce locking.

How do you manage transactions in your application?

ptamburro commented 5 years ago

Our jdbc connection is not in autocommit mode. We are using Spring data, and we are using a Standard Repository that extends CRUD Repository.

We added @Transactionals in the methods, but this increased the type errors "ABORTED: Aborted due to transient fault".


    @Override
    @Transactional
    public void updateSeeker(String seekerId, Seeker seeker) {
        // Precondiciones
        isNotNull(seeker, ErrorType.SEEKER_REQUIRED);
        isTrue(seekerRepository.existsById(seeker.getAccountId()), ErrorType.SEEKER_NOT_EXISTS);

        // Actualizamos
        saveSeeker(seeker);
    }
olavloite commented 5 years ago

Hi @ptamburro

I have just released version 1.1.3 of the jdbc driver, and this version includes additional logging functionality that could be used to debug these problems. I suspect that there might already be a transaction running before you are calling the repository methods, and as you are only specifying @Transactional, and not that it requires a new transaction, the methods would still be executed in the existing transactions.

I have updated the JPA example project to show how to use the logging feature to try to track down long running transactions: https://github.com/olavloite/spanner-jpa-example

olavloite commented 5 years ago

@ptamburro You could also have a look at this article: https://www.googlecloudspanner.com/2018/10/debugging-cloudspannersqlexception.html