Version: v6.1.0
I have a question. Today, while using sysbench to benchmark TiDB, I encountered a Write conflict. The transaction model used is tidb_txn_mode set to pessimistic. I don’t understand why this Write conflict is occurring.
In pessimistic mode, when autocommit is enabled, it will first commit in optimistic mode. If there is a conflict, it will switch to pessimistic mode. Compared to optimistic mode, pessimistic mode locks the key during the DML phase, which can block other sessions before committing. During the commit, it still executes in the optimistic mode’s prewrite+commit manner, and there may be write-write conflicts at this stage.
Teacher, in pessimistic mode, when autocommit is enabled, it will first commit in optimistic mode, and if there is a conflict, it will switch to pessimistic mode. For example, suppose the autocommit system variable is set to ON, and I directly execute an update statement (without begin and commit statements). When this update statement is finally committed, it is committed according to the optimistic transaction mode, right? (There is no need to check if the data is locked when modifying it; instead, it checks for write conflicts or lock conflicts at the commit stage.) Is this understanding correct?
In scenarios with severe conflicts or when a write conflict occurs, optimistic transactions will terminate directly, while pessimistic transactions will attempt to retry the statement with the latest data until there is no write conflict. Since TiDB’s locking operation is a write operation and the process involves reading before writing, it requires 2 RPCs. If a write conflict occurs during this process, it will retry. Each retry will log an entry, which does not require special attention. The number of retries is defined by pessimistic-txn.max-retry-count.
Write-write conflicts occur during the prewrite phase. When it is detected that another transaction is writing the current key (data.commit_ts > txn.start_ts), a write-write conflict will occur.
How should this data.commit_ts > txn.start_ts be understood? My test is as follows:
SESSION1:
SQL>begin;
SESSION2:
SQL>begin;
SQL>update test set name=‘DDD’ where id=4;
SQL>commit;
SESSION1:
SQL>insert into test values(4,‘ddddddd’);
ERROR 1062 (23000): Duplicate entry ‘4’ for key ‘PRIMARY’
Checking the tidb.log, it shows an error message indicating a pessimistic write conflict.
My SESSION2 has already committed, so why is it still showing a write-write conflict?
What you’re asking about is related to write-write conflicts in optimistic transactions, but it seems like your test is using pessimistic transactions.
I followed your test process, and with pessimistic transactions, there was no “pessimistic write conflict” error.
If it were an optimistic transaction, SESSION1 wouldn’t report an error during the insert; it would report a write conflict during COMMIT, not a Duplicate entry error.
Excuse me, teacher. Our TiDB version here is 5.3.1, set to pessimistic transaction mode, with the system variable autocommit set to ON and tidb_disable_txn_auto_retry set to ON. If the statement is automatically committed after execution, it will first be committed in optimistic transaction mode. If a write-write conflict is encountered during the commit process, will the transaction switch to pessimistic transaction mode, and then retry the write-write conflict in pessimistic transaction mode? During the retry process, will it reacquire the transaction’s start.tso, re-execute the statement, and restart the two-phase commit? Is this the process?