MySQL中的悲观锁与乐观锁_Mysql

来源:脚本之家  责任编辑:小易  

悲观锁2113与乐观锁是两种常见的资源并发锁设计思5261路,也是并发编程中4102一个非常基础的概念1653。本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍。悲观锁(Pessimistic Lock)悲观锁的特点是先获取锁,再进行业务操作,即“悲观”的认为获取锁是非常有可能失败的,因此要先确保获取锁成功再进行业务操作。通常所说的“一锁二查三更新”即指的是使用悲观锁。通常来讲在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select … for update操作来实现悲观锁。当数据库执行select for update时会获取被select中的数据行的行锁,因此其他并发执行的select for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。这里需要注意的一点是不同的数据库对select for update的实现和支持都是有所区别的,例如oracle支持select for update no wait,表示如果拿不到锁立刻报错,而不是等待,mysql就没有no wait这个选项。另外mysql还有个问题是select for update语句执行中所有扫描过的行都会被锁上,这一点很容易造成问题。因此如果在mysql中用悲观锁务必要确定走了索引,而不是全表扫描。乐观锁(Optimistic Lock)乐观锁的特点先进行业务操作,不到万不得已不去拿锁。即“乐观”的认为拿锁多半是会成功的,因此在进行完业务操作需要实际更新数据的最后一步再去拿一下锁就好。乐观锁在数据库上的实现完全是逻辑的,不需要数据库提供特殊的支持。一般的做法是在需要锁的数据上增加一个版本号,或者时间戳,然后按照如下方式实现:1. SELECT data AS old_data, version AS old_version FROM …;2. 根据获取的数据进行业务操作,得到new_data和new_version3. UPDATE SET data = new_data, version = new_version WHERE version = old_versionif (updated row > 0) {// 乐观锁获取成功,操作完成} else {// 乐观锁获取失败,回滚并重试}乐观锁是否在事务中其实都是无所谓的,其底层机制是这样:在数据库内部update同一行的时候是不允许并发的,即数据库每次执行一条update语句时会获取被update行的写锁,直到这一行被成功更新后才释放。因此在业务操作进行前获取需要锁的数据的当前版本号,然后实际更新数据时再次对比版本号确认与之前获取的相同,并更新版本号,即可确认这之间没有发生并发的修改。如果更新失败即可认为老版本的数据已经被并发修改掉而不存在了,此时认为获取锁失败,需要回滚整个业务操作并可根据需要重试整个过程。总结乐观锁在不发生取锁失败的情况下开销比悲观锁小,但是一旦发生失败回滚开销则比较大,因此适合用在取锁失败概率比较小的场景,可以提升系统并发性能乐观锁还适用于一些比较特殊的场景,例如在业务操作过程中无法和数据库保持连接等悲观锁无法适用的地方www.zgxue.com防采集请勿采集本网。

在关系型数据库中,悲观锁与乐观锁是解决资源并发场景的解决方案,接下来将详细讲解🔎一下这两个并发解决方案的实际使用及优缺点。

关于mysql中的乐观锁和悲观锁面试的时候被问到的概率还是比较大的。 mysql的悲观锁: 其实理解起来非常简单,当数据被外界修改持保守态度,包括自身系统当前

首先定义一下数据库,做一个最简单的库存表,如下设计:

乐观锁与悲观锁不同的是,它是一种逻辑上的锁,而不需要数据库提供锁机制来支持 当数据很重要,回滚或重试一次需要很大的开销时,需要保证操作的ACID性质,

CREATE TABLE `order_stock` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `oid` int(50) NOT NULL COMMENT '商品ID', `quantity` int(20) NOT NULL COMMENT '库存', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

这是两个不同的概念。 1.在表中增加version,是由你自己写的程序或者sql的where条件控制的,并没有真正的到达mysql的事务层。 2.悲观锁是mysql自己维护

quantity代表着不同商品oid的库存,接下来OCC及PCC使用此数据库进行演示。

乐观锁与悲观锁不同的是,它是一种逻辑上的锁,而不需要数据库提供锁机制来支持 当数据很重要,回滚或重试一次需要很大的开销时,需要保证操作的ACID性质,

乐观锁 OCC

乐观锁,悲观锁,这两个概念你需要搞清楚才能更好的理解。 乐观锁:与悲观锁相对应,不是数据库自带的,需要自己去实现。 悲观锁:与乐观锁相对应,是数据库自己

它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。

即“乐观锁🔒”认为拿锁的用户多半是会成功的,因此在进行完业务操作需要实际更新数据的最后一步再去拿一下锁就好。这样就可以避免使用数据库自身定义的行锁,可以避免死锁现象的产生。

UPDATE order_stock SET quantity = quantity - 1 WHERE oid = 1 AND quantity - 1 > 0;

乐观并发控制多数用于数据争用不大、冲突较少的环境中,这种环境中,偶尔回滚事务的成本会低于读取数据时锁定数据的成本,因此可以获得比其他并发控制方法更高的吞吐量。

悲观锁 PCC

它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作读某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。

这种设计采用了“一锁🔒二查🔍三更新”模式,就是采用数据库中自带 select ... for update 关键字进行对当前事务添加行级锁🔒,先将要操作的数据进行锁上,之后执行对应查询数据并执行更新操作。

BEGINSELECT quantity FROM order_stock WHERE oid = 1 FOR UPDATE;UPDATE order_stock SET quantity = 2 WHERE oid = 1; COMMIT;

MySQL还有个问题是select ... for update语句执行中所有扫描过的行都会被锁上,这一点很容易造成问题。因此如果在MySQL中用悲观锁务必要确定走了索引,而不是全表扫描。

悲观并发控制主要用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本的环境中。

OCC 和 PCC 优缺点

OCC 优点及缺点

【优点】

乐观锁相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁; 可以快速响应事务,随着并发量增加,但会出现大量回滚出现; 效率高,但是要控制好锁的力度。

【缺点】

如果直接简单这么做,还是有可能会遇到不可预期的结果,例如两个事务都读取了数据库的某一行,经过修改以后写回数据库,这时就遇到了问题; 随着并发量增加,但会出现大量回滚出现。

PCC 优点及缺点

【优点】

“先取锁再访问”的保守策略,为数据处理的安全提供了保证;

【缺点】

依赖数据库锁,效率低; 处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会; 降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数据。

以上就是MySQL中的悲观锁与乐观锁的详细内容,更多关于MySQL 悲观锁与乐观锁的资料请关注真格学网其它相关文章! 您可能感兴趣的文章:mysql 悲观锁与乐观锁的理解及应用分析Mysql悲观锁和乐观锁的使用示例实例讲解MySQL中乐观锁和悲观锁

悲观锁与乐观锁是2113两种常见的资源并发锁5261设计思路,也4102是并发编程中一个非常基础1653的概念。本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍。悲观锁(Pessimistic Lock)悲观锁的特点是先获取锁,再进行业务操作,即“悲观”的认为获取锁是非常有可能失败的,因此要先确保获取锁成功再进行业务操作。通常所说的“一锁二查三更新”即指的是使用悲观锁。通常来讲在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select … for update操作来实现悲观锁。当数据库执行select for update时会获取被select中的数据行的行锁,因此其他并发执行的select for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。这里需要注意的一点是不同的数据库对select for update的实现和支持都是有所区别的,例如oracle支持select for update no wait,表示如果拿不到锁立刻报错,而不是等待,mysql就没有no wait这个选项。另外mysql还有个问题是select for update语句执行中所有扫描过的行都会被锁上,这一点很容易造成问题。因此如果在mysql中用悲观锁务必要确定走了索引,而不是全表扫描。乐观锁(Optimistic Lock)乐观锁的特点先进行业务操作,不到万不得已不去拿锁。即“乐观”的认为拿锁多半是会成功的,因此在进行完业务操作需要实际更新数据的最后一步再去拿一下锁就好。乐观锁在数据库上的实现完全是逻辑的,不需要数据库提供特殊的支持。一般的做法是在需要锁的数据上增加一个版本号,或者时间戳,然后按照如下方式实现:1. SELECT data AS old_data, version AS old_version FROM …;2. 根据获取的数据进行业务操作,得到new_data和new_version3. UPDATE SET data = new_data, version = new_version WHERE version = old_versionif (updated row > 0) {// 乐观锁获取成功,操作完成} else {// 乐观锁获取失败,回滚并重试}内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • 详解mysql基本操作详细(二)
  • mysql数据校验过程中的字符集问题处理
  • linux下安装mysql数据库5.6源码安装,修改登录用户密码
  • mysql表,列,库增删改查问题小结
  • 深入浅析mysql 中 identifier case sensitivity问题
  • centos7离线安装mysql的教程详解
  • mysql主从数据库同步备份配置的方法
  • 解决mysql5.7安装后没有data文件夹无法登录的问题
  • mysql 5.7.19 免安装版遇到的坑(收藏)
  • 一个案例彻底弄懂如何正确使用mysql inndb联合索引
  • mysql 悲观锁和乐观锁的区别
  • mysql悲观锁和乐观锁的区别
  • mysql什么是悲观锁和乐观锁
  • 乐观锁和悲观锁是mysql的概念吗
  • mysql中的乐观锁和悲观锁怎么用
  • mysql数据库怎么设置乐观锁
  • mysql 使用乐观锁时,自带的悲观锁会失效么
  • mysql如何实现乐观锁
  • mysql默认是乐观锁?
  • mysql怎么设置悲观锁
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全mssqlmysqlmariadboracledb2mssql2008mssql2005sqlitepostgresqlmongodbredisaccess数据库文摘数据库其它首页mysql 悲观锁与乐观锁的理解及应用分析mysql悲观锁和乐观锁的使用示例实例讲解mysql中乐观锁和悲观锁详解mysql基本操作详细(二)mysql数据校验过程中的字符集问题处理linux下安装mysql数据库5.6源码安装,修改登录用户密码mysql表,列,库增删改查问题小结深入浅析mysql 中 identifier case sensitivity问题centos7离线安装mysql的教程详解mysql主从数据库同步备份配置的方法解决mysql5.7安装后没有data文件夹无法登录的问题mysql 5.7.19 免安装版遇到的坑(收藏)一个案例彻底弄懂如何正确使用mysql inndb联合索引mysql安装图解 mysql图文安装教程can""""t connect to mysql servwindows下mysql5.6版本安装及配置mysql字符串截取函数substring的mysql创建用户与授权方法mysql提示:the server quit withmysql日期数据类型、时间类型使用mysql——修改root密码的4种方法mysql update语句的用法详解mysql之timestamp(时间戳)用法linux下启动多个mysql服务器例子mysql常用命令汇总介绍mysql 安装失败的快速解决方法mysql 不等于 符号写法centos 6.5安装mysql5.7教程mysql用户权限管理实例分析mysql索引学习教程mysql存储引擎myisam与innodb区别总结整理mysql半同步复制原理配置与介绍详解mysql 优化日记
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved