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可能在总事务中拆分了很多小事务。用一下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锁
总结:就是所有涉及分表的操作,都带上分片字段条件
上一篇: Android Window 机制探索
下一篇: crontab定时任务管理器