apache / shardingsphere

Empowering Data Intelligence with Distributed SQL for Sharding, Scalability, and Security Across All Databases.
Apache License 2.0
19.94k stars 6.74k forks source link

DEADLOCK! DEADLOCK! DEADLOCK! #29734

Open fengzhongye opened 9 months ago

fengzhongye commented 9 months ago

Bug Report

Which version of ShardingSphere did you use?

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core</artifactId>
<version>5.4.1</version>
</dependency>

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-transaction-xa-core</artifactId>
<version>5.4.1</version>
</dependency>

Which project did you use? ShardingSphere-JDBC or ShardingSphere-Proxy?

ShardingSphere-JDBC

Expected behavior

Updating data based on primary key id will not deadlock

Actual behavior

Updating data based on primary key id will deadlock image.png

Reason analyze (If you can)

Steps to reproduce the behavior, such as: SQL to execute, sharding rule configuration, when exception occur etc.

This is my class.

@Override
@Transactional(isolation = Isolation.READ_COMMITTED)
public UniSegmentId getNextSegmentId(String bizType) {
        for (int i = 0; i < TinyIdConstants.RETRY; i++) {
            UniIdInfo tinyIdInfo = tinyIdInfoService.queryByBizType(bizType);
            if (tinyIdInfo == null) {
                throw new TinyIdSysException("找不到业务类型: " + bizType);
            }
            Long newMaxId = tinyIdInfo.getMaxId() + tinyIdInfo.getStep();
            Long oldMaxId = tinyIdInfo.getMaxId();

            int row = tinyIdInfoService.updateMaxId(tinyIdInfo.getId(), newMaxId, oldMaxId, tinyIdInfo.getVersion(), tinyIdInfo.getBizType());
            if (row == 1) {
                tinyIdInfo.setMaxId(newMaxId);
                return convert(bizType, tinyIdInfo);
            } else {
                log.info("版本号冲突:{}", tinyIdInfo);
            }
        }
    throw new TinyIdSysException("获取下一段冲突");
}

@Slf4j
@RestController
@Tag(name = "订单控制器")
@RequestMapping("/order")
@RequiredArgsConstructor
public class OrderController {

    private ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();

    @Resource
    private UniSegmentIdService idGeneratorFactoryServer;

    @GetMapping
    public void get(){
        for(int i = 0; i< 10000; i++){
            executorService.submit(() -> {
                idGeneratorFactoryServer.getNextSegmentId("NORMAL_ORDER_ITEM");
                idGeneratorFactoryServer.getNextSegmentId("NORMAL_ORDER");
            });
        }
    }

}

The same code, I have no problem using mybatis alone, but introducing shardingsphere will lead to deadlock

Example codes for reproduce this issue (such as a github link).

mybatis.zip mybatis+shardingjdbc.zip

fengzhongye commented 9 months ago

It’s not just a deadlock problem. We found several problems during stress testing, such as Cannot invoke method mod() on null object. and Routed target order_item_2 does not exist, available targets are `[order_0, order_1, order_2]. I'll send it out when I finish it.

fengzhongye commented 9 months ago

And the transaction has never been submitted

截屏2024-01-16 11 12 31
github-actions[bot] commented 8 months ago

There hasn't been any activity on this issue recently, and in order to prioritize active issues, it will be marked as stale.

fengzhongye commented 8 months ago
1709129784623
github-actions[bot] commented 7 months ago

There hasn't been any activity on this issue recently, and in order to prioritize active issues, it will be marked as stale.

fengzhongye commented 6 months ago

DEADLOCK

github-actions[bot] commented 5 months ago

There hasn't been any activity on this issue recently, and in order to prioritize active issues, it will be marked as stale.

DengQin commented 2 weeks ago

不只是死锁问题,我们在压测的时候还发现了几个问题,比如 Cannot Invoke Method Mod() On Null Object,路由目标 order_item_2 does not exist,可用目标是 `[order_0, order_1, order_2]。等我弄好了再发出来。

It’s not just a deadlock problem. We found several problems during stress testing, such as Cannot invoke method mod() on null object. and Routed target order_item_2 does not exist, available targets are `[order_0, order_1, order_2]. I'll send it out when I finish it.

Did you solve that problem? That happened to me ”Caused by: java.sql.SQLException: Unknown exception: Cannot invoke method hashCode() on null object“

terrymanu commented 2 weeks ago

Different problems please use separate issues.