当前位置: 首页 > 后端技术 > Java

详细介绍MySQL,一分钟教你解决MySQL死锁

时间:2023-04-02 01:24:45 Java

本文主要介绍mysql数据库死锁的原因及解决方法,和操作系统一样,数据库是多个用户使用的共享资源。当多个用户并发访问数据时,多个事务会同时访问数据库中的同一个数据。如果不控制并发操作,可能会读取和存储不正确的数据,破坏数据库的一致性。锁定是实现数据库并发控制的一项非常重要的技术。实际应用中经常会遇到锁相关的异常。当两个事务需要一组冲突的锁而无法继续事务时,就会发生死锁,严重影响应用程序的正常执行。数据库中有两种基本的锁类型:独占锁(X锁)和共享锁(S锁)。当一个数据对象被独占锁定时,其他事务不能读取或修改它。带有共享锁的数据对象可以被其他事务读取,但不能被修改。数据库使用这两种基本的锁类型来控制数据库事务的并发性。不用担心MySQL小白。今天也准备了一个mysql学习教程。进阶内容也有详细讲解,由浅入深,MySQL在线学习点击下方链接:https://www.bilibili.com/video...MySQL资料下载:http://www.bjpowernode.com/?s..死锁第一种情况:用户A访问表A(锁住表A),然后访问表B;另一个用户B访问表B(锁定表B),然后尝试访问表A;此时,由于用户B已经锁定了B表,用户A必须等待用户B释放B表才能继续。同样,用户B必须等待用户A释放表A才能继续,这就造成了死锁。解决办法:这种死锁比较常见,是程序有bug导致的。没有别的办法,只能调整程序的逻辑。仔细分析程序的逻辑。对于多表数据库操作,尽量按相同顺序处理,尽量避免同时锁定两种资源。比如在操作A和B两张表时,始终按照A和B的顺序进行处理,当两个资源必须同时加锁时,必须保证任何时候资源加锁的顺序相同.死锁第二种情况:用户A查询一条记录,然后修改记录;此时用户B修改了记录。此时用户A的事务中的锁的性质从查询的共享锁尝试提升为排它锁。用户B中的排他锁必须等待A释放共享锁,因为A有共享锁,而A中的排他锁由于B的排他锁无法升起而无法释放共享锁,因此发生死锁。这种死锁比较隐蔽,但在稍大的项目中经常发生。比如在某个项目中,页面上的按钮被点击后,按钮并没有立即失效,这样用户很快就会多次点击同一个按钮,从而使同一段代码对同一个按钮进行多次操作记录在数据库中,这种死亡很容易发生。锁盒。解决方法:1、对于按钮等控件,点击后立即失效,防止用户重复点击,避免同时对同一条记录进行操作。2.使用乐观锁进行控制。乐观锁大多是基于数据版本(Version)记录机制来实现的。也就是给数据加上版本标识。在基于数据库表的版本方案中,一般是通过在数据库表中增加一个“版本”字段来实现的。读出数据的时候,一起读这个版本号,以后更新的时候,这个版本号加一。此时将提交数据的版本数据与数据库表中相应记录的当前版本信息进行比较。如果提交数据的版本号大于当前数据库表的版本号,则更新,否则视为过期数据。乐观锁机制避免了在长事务中锁定数据库的开销(用户A和用户B在操作过程中都没有锁定数据库数据),大大提高了系统在大并发下的整体性能。Hibernate在其数据访问引擎中内置了乐观锁定实现。需要注意的是,由于我们系统实现了乐观锁机制,外部系统的用户更新操作不受我们系统的控制,所以可能会更新到数据库中的脏数据。3.使用悲观锁进行控制。大多数情况下,悲观锁是通过数据库的锁机制来实现的,比如Oracle的Select...forupdate语句,来保证操作的最大程度的排他性。但随之而来的是数据库性能上的大量开销,尤其是对于长事务,这样的开销往往是难以承受的。例如,在金融系统中,当操作者读取用户数据,并根据读取到的用户数据进行修改(如更改用户账户余额)时,如果采用悲观锁机制,则意味着整个操作过程中整个过程(从操作员读取数据,开始修改,到提交修改结果,甚至包括操作员中途去煮咖啡的时间),数据库记录始终处于锁定状态。可以想象,如果面对成百上千的并发,这样的情况会导致灾难性的后果。所以在使用悲观锁进行控制的时候一定要考虑清楚。死锁的第三种情况:如果事务中执行了不满足条件的update语句,则进行全表扫描,将行级锁升级为表级锁。多个这样的事务执行后,很容易产生死锁和阻塞。类似的情况,当表的数据量很大,而索引太小或不合适时,经常会出现全表扫描,最终应用系统会越来越慢,最终会出现阻塞或死锁。解决方法:在SQL语句中不要使用过于复杂的多表关联查询;使用“执行计划”对SQL语句进行分析,对于全表扫描的SQL语句,建立相应的索引进行优化。总结一般来说,内存溢出和表锁都是代码写得不好导致的,所以提高代码质量是最根本的解决办法。有人认为先实现功能是不对的,测试阶段有bug再改正。正如产品的质量是在制造过程中决定的,而不是在质量测试中决定的,软件的质量在设计和编码阶段就已经确定了,而测试只是对软件质量的验证,因为测试是不可能的。软件中的错误。你学会了吗!!!