pingcap / pingcap/tidb

Transaction exceeding ttl does not release the lock

Open
#49,184 4 comments 0 reactions 0 assignees View on GitHub
sig/transaction 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
t1 | t2

begin;

select * from t1;
+------+------+
| a | b |
+------+------+
| 3 | 2 |
| 2 | 3 |
+------+------+
begin;

select * from t1;
+------+------+
| a | b |
+------+------+
| 3 | 2 |
| 2 | 3 |
+------+------+

delete from t1 where a=3;

update t1 set a=4 where a=3;

select * from t1;

commit;

select * from t1;

commit;
```

The codes are modified from @zyguan's code , and here is the [link](https://gist.github.com/zyguan/bf2ba336fc7902f3b279535417905554).

```javascript
Deno.test('test', async () => {
const c1 = await mysql.createConnection({ host: TIDB_HOST, port: 4000, user: "root", database: 'test' });
const c2 = await mysql.createConnection({ host: TIDB_HOST, port: 4000, user: "root", database: 'test' });
try {
// await c1.query("set @@tidb_general_log=1, @@innodb_lock_wait_timeout=600");
await c1.query("set @@tidb_general_log=1");
await c1.query("drop table if exists t1");
await c1.query("create table t1 (a int, b int)");
await c1.query("insert into t1 values (3, 2), (2, 3)");
log("show config", await pp(c1.query("show config where name like '%max-txn-ttl'")));

await c1.query("begin");
log("t1 select(o1):", await pp(c2.query("select * from t1")));

await c2.query("begin");
log("t2 select:", await pp(c2.query("select * from t1")));
log("t2 delete:", await pp(c2.query("delete from t1 where a=3")));

log("t1 update(o2):", await pp(c1.query("update t1 set a=4 where a=3")));

log("t2 select:", await pp(c2.query("select * from t1")));

log("t1 select(o3):", await pp(c1.query("select * from t1")));
log("t1 select(o3'):", await pp(c1.query("select * from t1")));

log("t2 commit:", await pp(c2.query("commit")));

log("t1 commit:", await pp(c1.query("commit")));

} finally {
await close(c1);
await close(c2);
}
});
```

### 2. What did you expect to see? (Required)

Since we set `max-txn-ttl` to 30s, and `innodb_lock_wait_timeout` is 50s. The `update` in t1 will wait for the `delete` in t2 to release the lock. Theoretically, `update` will be executed successfully after waiting for 30 seconds since t2 exceeds the ttl.

### 3. What did you see instead (Required)

The `update` in t1 will return two result:

1. `update` was executed successfully, but took about 35 seconds.
2. `update` returns an error: "MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction".

It seems that result 2 is unexpected. Since this error is returned, it means that the waiting time of t1 exceeds 50 seconds, and this time has exceeded ttl, which is 30 seconds, so t2 should theoretically have released the lock.

### 4. What is your TiDB version? (Required)

tidb_version(): Release Version: v7.4.0
Edition: Community
Git Commit Hash: 38cb4f3312be9199a983c0ef282d2ea2e28a7824
Git Branch: heads/refs/tags/v7.4.0
UTC Build Time: 2023-10-10 14:18:50
GoVersion: go1.21.1
Race Enabled: false
Check Table Before Drop: false
Store: tikv

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.