两阶段加锁
在分布式领域,熟悉一些基本的概念,比如,2PC,3PC,最近在优化一个项目的数据访问,接触到一个概念:2PL,两阶段锁, innodb引擎里面的加锁协议,保证单机事务的隔离和一致性。
例子
先看下面两个方案:
方案一:
1 | begin; |
方案二:
1 | begin; |
哪个方案更好?
实际上,这取决于数据库里面,那些是热点数据. 下面是2PL的执行过程:
Mysql执行事务的时候,会分为两个阶段执行加锁/解锁:
- 在事务中只有提交(commit)或者回滚(rollback)时才是解锁阶段,
- 其余时间为加锁阶段。
可以看出,方案一里面,对库存持有的锁的时间更长,因为加锁完毕后,还有等待对订单库的操作,而在我们的系统(商品中心),库存又是一个热点数据,那么, 自然更好的优化方案是第二个。
小结
理解2PL有助于更好的优化sql语句,尽量减少事务的粒度,除了提高性能外还可以减少死锁的可能性;不过要注意的是,2PL不能防止死锁,因为每次获得锁的操作还是分开的,可以看看:严格两阶段封锁协议和强两阶段封锁协议。