sharding jdbc单库分表事物问题

技术使用

  • 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锁

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值