热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

MySQL中如何书写update避免表锁

MySQL中如何书写update避免表锁,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的

MySQL中如何书写update避免表锁,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

今天,我来说另外一个面试题。为什么推荐 MySQL 的 update 语句中 where 条件要有主键?

看到这个问题的朋友,我相信不少人有疑问,我 where 不加主键还不能更新了?

不是的,能更新,也能使用。但是我不建议你们这样做。因为我们大多数人使用 MySQL 都使用的是 innodb 存储引擎,它是支持事务的。如果你的 where 条件不加主键,那么 innodb 的行级锁就可能变成表级锁。如果升级为表级锁,那么并发性就将大打折扣了。

行锁升级为表锁与事务的隔离级别有关,因为事务的隔离性是靠加锁来实现的,而加锁不当势必会影响并发。

不一样的锁,支持的并发也是不一样的。而最终加什么样的锁,与索引也有莫大的关系,因此,可以说采用什么样的索引决定了支持多少并发。

常用的索引有三类:主键、唯一索引、普通索引。主键我就不再细说,自带最高效的索引属性;唯一索引指的是该属性值重复率为 0,一般可作为业务主键,例如订单号;普通索引 与前者不同的是,属性值的重复率大于 0,不能作为唯一指定条件,例如购买用户的姓名。今天我主要想说的是“普通索引对并发的影响”。

没有索引的情况,我就不说了,那对并发来说肯定是灾难,死锁估计是常有的事。

为什么我推荐 update 中 where 条件加入主键呢?

因为主键是唯一索引,你用其他唯一索引也可以,但是一般的表,可能只有主键才是唯一的。所以,我建议你更新的时候,记住加上主键就行了。

你只需要记住主键和唯一索引是行锁,其他索引并不一定是行锁,很可能是表锁。这样,死锁的概率就非常的高,并发也就随之下降。

下面我们通过一个简单的例子来看一下,普通索引的情况。

相关建表语句,索引,和数据如下所示:

MySQL中如何书写update避免表锁

然后取消事务自动提交 set autocommit = off;

当我们表里面创建时间重复率比较高的时候。分别开启两个窗口,两个事务。

MySQL中如何书写update避免表锁

为了演示,你可以把数据量加多点,比如 03-01 和 03-02 的数据各 10 万条。

依次执行两个窗口中的 SQL,你会发现,其中一个窗口中的更新失败了。提示:

MySQL中如何书写update避免表锁

看似这两个事务不互相干,但是在其中一个事务中更新自己锁定的数据失败后,应该能说明在此时引发了表锁。这是在非主键索引或者说是唯一索引,并且索引数据重复量比较高的情况下,你的更新发生量表锁。并发能力就会大大下降!

你们可以试一下,如果此时使用主键或唯一索引会不会这样。

在我们的电商系统中,这样的代码并不少。在一些热门商品和秒杀、优惠、打折等活动中经常会发生一些莫名其妙的异常,导致用户体验大打折扣。

上面的测试数据,你把它们全部删除,然后再新增一些数据,这些数据中在 create_time 重复率为 0 的情况下,你会发现两个事务就都能成功了。这说明它们这时用的应该是行级锁,效率更高。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程笔记行业资讯频道,感谢您对编程笔记的支持。


推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了通过mysql命令查看mysql的安装路径的方法,提供了相应的sql语句,并希望对读者有参考价值。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 本文介绍了在Oracle数据库中创建序列时如何选择cache或nocache参数。cache参数可以提高序列的存取速度,但可能会导致序列丢失;nocache参数可以避免序列丢失,但在高并发访问时可能导致性能问题。文章详细解释了两者的区别和使用场景。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • mysql-cluster集群sql节点高可用keepalived的故障处理过程
    本文描述了mysql-cluster集群sql节点高可用keepalived的故障处理过程,包括故障发生时间、故障描述、故障分析等内容。根据keepalived的日志分析,发现bogus VRRP packet received on eth0 !!!等错误信息,进而导致vip地址失效,使得mysql-cluster的api无法访问。针对这个问题,本文提供了相应的解决方案。 ... [详细]
  • 众筹商城与传统商城的区别及php众筹网站的程序源码
    本文介绍了众筹商城与传统商城的区别,包括所售产品和玩法不同以及运营方式不同。同时还提到了php众筹网站的程序源码和方维众筹的安装和环境问题。 ... [详细]
  • ubuntu用sqoop将数据从hive导入mysql时,命令: ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
author-avatar
纸灰机forever
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有