两阶段封锁协议

参考 https://segmentfault.com/a/1190000012513286

定义

两段锁协议是指每个事务的执行分为两个阶段:生长阶段(加锁阶段)和衰退阶段(解锁阶段)。
加锁阶段:在该阶段可以进行加锁操作。在对任何数据进行读操作之前要申请并获得S锁,在进行写操作之前要申请并获得X锁。加锁不成功,则事务进入等待状态,直到加锁成功才继续执行。
解锁阶段:当事务释放了一个封锁以后,事务进入解锁阶段,在该阶段只能进行解锁操作不能再进行加锁操作。
两段封锁法可以这样来实现:事务开始后就处于加锁阶段,一直到执行ROLLBACK和COMMIT之前都是加锁阶段。ROLLBACK和COMMIT使事务进入解锁阶段,即在ROLLBACK和COMMIT模块中DBMS释放所有封锁 。

简单来说就是解锁之后不能再加锁 。
在这里插入图片描述
加锁时机
当对记录进行更新操作或者select for update(X锁)、lock in share mode(S锁)时,会对记录进行加锁。
解锁时机
commit或者rollback时。

一个例子

这道题来自牛客网,根据上面的解释,很显然T1是遵守两阶段封锁协议。在这里插入图片描述

二段锁对性能的影响实例

下面举个具体的例子,来讲述二段锁对应用性能的影响,我们举个库存扣减的例子:

方案一:
start transaction;
// 锁定用户账户表
select * from t_accout where acount_id=234 for update
//生成订单
insert into t_trans;
// 减库存
update t_inventory set num=num-3 where id=${id} and num>=3;
commit;
方案二:
start transaction;
// 减库存
update t_inventory set num=num-3 where id=${id} and num>=3;
// 锁定用户账户表
select * from t_accout where acount_id=234 for update
//生成订单
insert into t_trans;
commit;

我们的应用通过JDBC操作数据库时,底层本质上还是走TCP进行通信,MySQL协议是一种停-等式协议(和http协议类似,每发送完一个分组就停止发送,等待对方的确认,在收到确认后再发送下一个分组),既然通过网络进行通信,就必然会有延迟,两种方案的网络通信时序图如下:

在这里插入图片描述
由于商品库存往往是最致命的热点,是整个服务的热点。如果采用第一种方案的话,TPS理论上可以提升3rt/rt=3倍。而这是在一个事务中只有3条SQL的情况,理论上多一条SQL就多一个rt时间。

另外,当更新操作到达数据库的那个点,才算加锁成功。commit到达数据库的时候才算解锁成功。所以,更新操作的前半个rt和commit操作的后半个rt都不计算在整个锁库存的时间内。

从上面的例子可以看出,在一个事务操作中,将对最热点记录的操作放到事务的最后面,这样可以显著地提高服务的吞吐量。

select for update 和 update where的最优选择

我们可以将一些简单的判断逻辑写到update操作的谓词里面,这样可以减少加锁的时间,如下:

方案一:
start transaction
num = select count from t_inventory where id=234 for update
if count >= 3:
    update t_inventory set num=num-3 where id=234
    commit 
else:
    rollback
方案二:
start transaction:
    int affectedRows = update t_inventory set num=num-3 where id=234 and num>=3
    if affectedRows > 0:
        commit
    else:
        rollback

延时图如下:
在这里插入图片描述
从上图可以看出,加了update谓词以后,一个事务少了1rt的锁记录时间(update谓词和select for update对记录加的都是X锁,所以效果是一样的)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值