欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

sharding jdbc单库分表事物问题

程序员文章站 2024-03-21 17:07:40
...

技术使用

  • mysql
  • Spring Data Jpa
  • sharding jdbc
  • Spring boot

项目没有拆分,因为是收费相关的。采用的是单体服务。

问题复现

	在进行某笔账单进行红冲调整后,遇到了锁等待的问题。一下是自己的排查路径
  • 数据库查明是哪个表被锁住,导致锁等待
-- 查询是否锁表
show OPEN TABLES where In_use > 0;


-- 查询进程
show full  processlist ;




但是一个事物里面怎么会锁表,联想到最近这个表因为数据量大才被分表。初步怀疑是分表后导致的问题。于是上网查询了sharding的原理:可以有一张图来显示

sharding jdbc单库分表事物问题
猜想因为设计到分表的事务,sharding可能在总事务中拆分了很多小事务。用一下sql语句验证了下


-- 查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; 

-- 查看等待锁的事务
SELECT * FROM information_schema.innodb_lock_waits  ;


-- 查看当前的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

果然在进行更新的时候拆分了事务,数据库显示一共有33条事务。但是33个事务是针对不同33个表,按理来说也不会进行锁表。

最终问题

在仔细查看了代码后,因为这里涉及了调取别人的代码,发现别人也更新了这个表。也就是说在总事务下有2个地方更新了这个表。后面采取更新带上分表条件,也就是月份,这样对于只会有开一个事务,因为有明确的条件。sharding不会在拆分很多个,最后组装。这样问题是解决了。

猜测是太多update后insert导致的。如果有人看到这个问题,麻烦请解答下。

第一:我们是根据年月字段分片的所以同事务中,只有命中分片规则或命中主键缓存的语句,才能事务上下文共享。
第二:分表更新WHERE条件中,需要强制带分表字段。否则极有可能会GAP锁

总结:就是所有涉及分表的操作,都带上分片字段条件

相关标签: 高并发