博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅析MySQL二段锁
阅读量:6436 次
发布时间:2019-06-23

本文共 1706 字,大约阅读时间需要 5 分钟。

背景

在介绍MySQL二段锁之前,我需要理清一下概念,即MySQL二阶段加锁与二阶段提交的区别:

二阶段加锁:用于单机事务中的一致性和隔离性二阶段提交:用于分布式事务

何为二段锁

在一个事务操作中,分为加锁阶段解锁阶段,且所有的加锁操作在解锁操作之前,具体如下图所示:

alt text

加锁时机

当对记录进行更新操作或者select for update(X锁)、lock in share mode(S锁)时,会对记录进行加锁,锁的种类很多,不在此赘述。

何时解锁

在一个事务中,只有在commit或者rollback时,才是解锁阶段。

二阶段加锁最佳实践

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

方案一: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协议类似,每发送完一个分组就停止发送,等待对方的确认,在收到确认后再发送下一个分组),既然通过网络进行通信,就必然会有延迟,两种方案的网络通信时序图如下:

alt text

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

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

性能优化

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

select for update 和 update where的最优选择

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

方案一:start transactionnum = select count from t_inventory where id=234 for updateif 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

延时图如下:

alt text

从上图可以看出,加了update谓词以后,一个事务少了1rt的锁记录时间(update谓词和select for update对记录加的都是X锁,所以效果是一样的)。

死锁

加锁SQL都或多或少会遇到这个问题。上面的最佳实践中,笔者建议在一个事务中,对记录的加锁按照记录的热点程度升序排列,对与任何会并发的SQL都必须按照相同的顺序来处理,否则会导致死锁,如下图:

alt text

总结

合理地写好SQL,对于我们提高系统的吞吐量至关重要。

原文链接

转载地址:http://aohga.baihongyu.com/

你可能感兴趣的文章
MIT 学生挑战新泽西索取挖矿程序源代码的要求
查看>>
mozjpeg:JPEG图片压缩5%,获Facebook支持
查看>>
聊聊Service(一)
查看>>
即将到来的 Android N 将具备这些新特性
查看>>
《善用佳软:高效能人士的软件应用之道》一2.6 小工具之计算器
查看>>
《C语言编程初学者指南》一1.9 本章小结
查看>>
《Spark大数据分析:核心概念、技术及实践》一3.5 API
查看>>
《“笨办法”学Python(第3版)》——习题3 数字和数学计算
查看>>
《无人机DIY》——4.2 项目1:MakerBeam机身
查看>>
阿里数据库内核月报:2015年11月
查看>>
swfheader 0.10 Released(已更正下载地址)
查看>>
SQL Server使用视图做权限控制
查看>>
深入浅出LVS:企业集群平台负载均衡的三种模式和算法实现
查看>>
twitter storm源码走读(二)
查看>>
jQuery学习笔记之DOM操作、事件绑定(2)
查看>>
写入指定长度的字节到文件
查看>>
删除数据表和清空数据表的内容(保存表结构)的SHELL脚本
查看>>
C# 视频监控系列(14):总结贴——VC++代码转成C#小结
查看>>
undefined与null的区别
查看>>
Android特效专辑(十二)——仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View...
查看>>