atlassian-labs / db-replica

Automatically chooses between database connections to read-write main or read-only replica
Apache License 2.0
10 stars 11 forks source link

Issue/none lsn not propagated after close #154

Closed wyrzyk closed 2 years ago

wyrzyk commented 2 years ago

I think it may be the issue we observe in the product:

  1. We get a connection from the transaction-thread local.
  2. We prepare a statement and executeUpdate without calling commit.
  3. We close the connection

The transaction is never committed on the DualConnection layer, so we never register ReplicaConsistency#write, and we don't store the last write. The following connection assumes the replica is consistent.

Why was the data persistent by the update without calling commit?

It's because we have a hook:

.addOnClose((rawConnection, timeTaken) -> {
                boolean autocommit = rawConnection.getAutoCommit();
                if (!autocommit) {
                    rawConnection.setAutoCommit(true);
                }
            });

The hook calls setAutoCommit(true) if the auto-comit was set to false, and according to the Connection docs: "If this method is called during a transaction and the auto-commit mode is changed, the transaction is committed.".

wyrzyk commented 2 years ago

I think the issue is in the product. Transactions should be committed explicitly without relying on a hook's side effects. There is probably more than one place that misbehaves this way. I'll try to fix it on the db-replica side (or et least detect and warn about the issue).