[CONJ-729] Read-only transaction with auto-commit=false not committed when using Master/slave or Aurora configuration Created: 2019-09-04  Updated: 2019-09-13  Resolved: 2019-09-12

Status: Closed
Project: MariaDB Connector/J
Component/s: aurora, Failover
Affects Version/s: 2.4.0, 2.4.1, 2.4.2, 2.4.3
Fix Version/s: 2.4.4

Type: Bug Priority: Blocker
Reporter: Lenne Assignee: Diego Dupin
Resolution: Fixed Votes: 0
Labels: None


 Description   

Setup

  • Aurora cluster with
    Master with READ_COMMITTED isolation level
    Read replica (uses REPEATABLE_READ isolation by default in Aurora)
  • We set auto-commit to false on the Hikari connection pool
  • We use Spring with @Transactional(readOnly=true)

    @Transactional(readOnly=true)
    public String getCount() {
        return jdbcTemplate.executeQuery("SELECT count(*) FROM some_table", ...);
    }
    

Issue:
When we execute the getCount method multiple times we always get the same count, even though items are added to the some_table between invocations of getCount.

Findings
This is caused by not performing a commit after the invocation of getCount.
In the MariaDbConnection.commit method the protocol.inTransaction() returns false.
So the st.execute("COMMIT") is never actually invoked, although Spring tries to commit the transaction.

Since Aurora read instances are always REPEATABLE_READ, and we use auto-commit false, the transaction will be kept alive without a COMMIT, which explains the stale date.

When we use driver version 2.3.0 we don't see this issue since protocol.inTransaction() correctly indicates the transaction is active, and a commit occurs at the end of the getCount method.
Starting from version 2.4.0 we see this erroneous behaviour.

We have currently reverted back to version 2.3.0.



 Comments   
Comment by Lenne [ 2019-09-06 ]

While debugging it seemed like

  • the commit was happening on the same MariaDbConnection object instance as the one that was used to create the prepared statement for the select query.
  • but the AuroraPool object that was used for the select (masterconnection=false) was different from the one on which the pool.inTransaction() call was performed (this one had masterconnection=true).

So it seems like it was trying to commit on the connection to the master, which did not have a transaction running, instead of on the connection to the slave.

Generated at Thu Feb 08 03:17:53 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.