pingcap / pingcap/tidb

Execution of the transactions violates atomicity.

Open
#59,792 4 comments 0 reactions 0 assignees View on GitHub
type/question
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.