apache / apache/incubator-seata

GlobalSession中对status的update操作没有加锁,在并发场景下可能会导致事务最终永远失败

Open
#2,840 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
26k
Forks
8.8k
Avg merge
1d 8h
Merged PRs (30d)
4

Description

- [x] I have searched the [issues](https://github.com/seata/seata/issues) of this repository and believe that this is not a duplicate.

### Ⅰ. Issue Description
DB存储模式下,GlobalSession中对status的update操作没有加锁,并发场景下可能会导致分布式事务永远不会成功

### Ⅱ. Describe what happened

**线程A:** 正常执行一个分布式事务,假设整个分布式事务执行时间较长,最终对应GLobalSession中的status状态还是被更新为commit,并且部分或者全部分支事务参与方已经执行commit操作成功。

**线程B:** 线程B为DefaultCoordinator中执行timeoutCheck的定时任务,假设timeoutCheck获取所有事务的时候线程A的GlobalSession还是Begin状态,由于该GlobalSession执行时间较长被判定为超时,此时就可能在线程A更新为commit状态之后重新被更新为TimeoutRollbacking,然后由其他定时任务开始执行回滚操作。

这样就会导致GlobalSession的状态从begin -> commit -> TimeoutRollbacking。而在这个过程中一些事物参与方已经执行过commit了,再次被要求执行rollback时就可能会报错,并且永远不会成功,事务会一直处于中间状态(一部分参与方已经提交,一部分参与被要求回滚,全局事务被标记为回滚)

```
Just paste your stack trace here!
```

### Ⅲ. Describe what you expected to happen
对事务状态的更新需要考虑并发问题,个人认为任何场景下事务允许失败,但是不能处于一个坏的、不可恢复的状态。

### Ⅳ. How to reproduce it (as minimally and precisely as possible)

并发场景,不容易复现。
1. xxx
2. xxx
3. xxx

### Ⅴ. Anything else we need to know?

### Ⅵ. Environment:

- JDK version :
- OS :
- Others:

Contributor guide

Open the contributing guide

Research direction

Start by reading GlobalSession status updates and the DefaultCoordinator timeoutCheck path in DB storage mode. Trace concurrent commit and timeout handling, then verify that a transaction cannot move from commit to TimeoutRollbacking and remain unrecoverable under concurrent execution.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
databases, distributed-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.