分布式场景下,锁的粒度和事务的粒度,如何控制?
业务背景
- 场景:在线电商平台的订单提交与库存扣减系统
- 用户行为:用户在商品详情页点击「立即下单」后,系统需同时完成以下操作:
- 创建订单记录:在订单服务中插入新订单数据(涉及订单表);
- 扣减商品库存:在库存服务中更新商品库存(涉及库存表);
- 发送支付回调:异步通知支付系统处理支付结果。
- 系统架构:
- 基于微服务架构,订单服务与库存服务独立部署,数据库使用MySQL(InnoDB引擎)
- 分布式锁通过Redis实现,
- 核心矛盾:在使用分布式锁与事务注解(如 Spring 的 @Transactional)一起时,分布式锁的位置(锁在事务外,还是事务内),分别有什么优缺点?怎么用?
回答
1、锁的粒度 > 事务粒度
- 优点:事务的时长不受锁的影响。
- 缺点:锁的时间会更长,跨越了整个事务。系统吞吐也会更低。
2、事务的粒度 > 锁粒度
-
优点:锁的时长比较短,并发度会更高一些。
-
缺点:
-
在事务中进行了外部调用(redis 锁),可能会拖长事务、占用数据库链接等问题。
-
可能会导致数据不一致(重点)。
-
3、如何选择?
-
建议考虑先加锁,再加事务。
可以有效的避免数据库链接被占用、导致数据不一致等问题。
锁粒度变大,这个是可接受的。