Execution of the transactions violates atomicity.
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
Please answer these questions before submitting your issue. Thanks!
### 1. Minimal reproduce step (Required)
```sql
use test;
drop table if exists table1;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; // both two session
create table table1(a int primary key, b int);
insert into table1(a, b) values(3, 3), (4, 4), (5, 5);
```
| T1 | T2 | Result |
| :------------------------------------ | :----------------------------------- | :----- |
| begin; | | ok |
| | begin; | ok |
| update table1 set b = 10 where a = 3; | | ok |
| | insert into table1 values (9, 9); | ok |
| | update table1 set b = 8 where a = 4; | ok |
| update table1 set b = 11 where a > 5; | | ok |
| select * from table1 where a != 1; | | ok |
| | commit; | ok |
| commit; | | ok |
So, the final execute sequence is T2 -> T1 ( T2 commit first, T1 commit second )
All the workload finished,
the finally result is:
```sql
mysql> select * from table1;
+---+------+
| a | b |
+---+------+
| 3 | 10 |
| 4 | 8 |
| 5 | 5 |
| 9 | 9 |
+---+------+
4 rows in set (0.00 sec)
```
But the real commit is T2 first, T1 second, so the last row should be (a,b) = (9,11)
To ensure the execution order of transactions and under the condition that both transactions (T1 and T2) were successfully executed and committed.
The second `UPDATE` statement in **T1** was not actually executed, this violates the **atomicity** of ACID properties.
### 2. What did you expect to see? (Required)
When T1 execute the second update, Mysql will waiting, until T2 commit;
```sql
mysql> update table1 set b = 11 where a > 5;
-- waiting
```
And Mysql v8.4 final result is in the following:
```sql
mysql> select * from table1;
+---+------+
| a | b |
+---+------+
| 3 | 10 |
| 4 | 8 |
| 5 | 5 |
| 9 | 11 |
+---+------+
4 rows in set (0.00 sec)
```
MySQL v8.4 can correctly handle this scene, and promise the atomicity of ACID.
### 3. What did you see instead (Required)
When T1 execute the second update, TiDB returns ok.
```sql
mysql> update table1 set b = 11 where a > 5;
-- ok
```
And TiDB final result is in the following:
```sql
mysql> select * from table1;
+---+------+
| a | b |
+---+------+
| 3 | 10 |
| 4 | 8 |
| 5 | 5 |
| 9 | 9 |
+---+------+
4 rows in set (0.00 sec)
```
TiDB can not promise the atomicity of ACID.
### 4. What is your TiDB version? (Required)
TiDB v8.5.0
```sql
Release Version: v8.5.0
Edition: Community
Git Commit Hash: d13e52ed6e22cc5789bed7c64c861578cd2ed55b
Git Branch: HEAD
UTC Build Time: 2024-12-18 02:26:06
GoVersion: go1.23.3
Race Enabled: false
Check Table Before Drop: false
Store: tikv
```
Contributor guide
Research direction
Start by running the provided two-session SQL reproduction against TiDB v8.5.0 and compare its behavior with MySQL 8.4. Trace the transaction and locking paths responsible for the second T1 update; done means the update waits appropriately and the final row with a=9 has b=11, with a regression test covering the sequence.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- mysql, sql
- Domain
- databases, distributed-systems
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100