这篇文章主要介绍了mysql数据库锁的产生原因及解决办法,需要的朋友可以参考下
 

数据库和操作系统一样,是一个多用户使用的共享资源。当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。加锁是实现数据库并 发控制的一个非常重要的技术。在实际应用中经常会遇到的与锁相关的异常情况,当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就会出现死锁,严 重影响应用的正常执行。

在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两 种基本的锁类型来对数据库的事务进行并发控制。

死锁的第一种情况

一个用户A 访问表A(锁住了表A),然后又访问表B;另一个用户B 访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这就死锁就产生了。

解决方法:

这种死锁比较常见,是由于程序的BUG产生的,除了调整的程序的逻辑没有其它的办法。仔细分析程序的逻辑,对于数据库的多表操作时,尽量按照相同的顺序进 行处理,尽量避免同时锁定两个资源,如操作A和B两张表时,总是按先A后B的顺序处理, 必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源。

死锁的第二种情况

用户A查询一条纪录,然后修改该条纪录;这时用户B修改该条纪录,这时用户A的事务里锁的性质由查询的共享锁企图上升到独占锁,而用户B里的独占锁由于A 有共享锁存在所以必须等A释放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。这种死锁比较隐蔽,但在稍大点的项 目中经常发生。如在某项目中,页面上的按钮点击后,没有使按钮立刻失效,使得用户会多次快速点击同一按钮,这样同一段代码对数据库同一条记录进行多次操 作,很容易就出现这种死锁的情况。

解决方法:

1、对于按钮等控件,点击后使其立刻失效,不让用户重复点击,避免对同时对同一条记录操作。
2、使用乐观锁进行控制。乐观锁大多是基于数据版本(Version)记录机制实现。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是 通过为数据库表增加一个“version”字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数 据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。乐观锁机制避免了长事务中的数据 库加锁开销(用户A和用户B操作过程中,都没有对数据库数据加锁),大大提升了大并发量下的系统整体性能表现。Hibernate 在其数据访问引擎中内置了乐观锁实现。需要注意的是,由于乐观锁机制是在我们的系统中实现,来自外部系统的用户更新操作不受我们系统的控制,因此可能会造 成脏数据被更新到数据库中。
3、使用悲观锁进行控制。悲观锁大多数情况下依靠数据库的锁机制实现,如Oracle的Select … for update语句,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。如一个金融系统, 当某个操作员读取用户的数据,并在读出的用户数据的基础上进行修改时(如更改用户账户余额),如果采用悲观锁机制,也就意味着整个操作过程中(从操作员读 出数据、开始修改直至提交修改结果的全过程,甚至还包括操作员中途去煮咖啡的时间),数据库记录始终处于加锁状态,可以想见,如果面对成百上千个并发,这 样的情况将导致灾难性的后果。所以,采用悲观锁进行控制时一定要考虑清楚。

死锁的第三种情况

如果在事务中执行了一条不满足条件的update语句,则执行全表扫描,把行级锁上升为表级锁,多个这样的事务执行后,就很容易产生死锁和阻塞。类似的情 况还有当表中的数据量非常庞大而索引建的过少或不合适的时候,使得经常发生全表扫描,最终应用系统会越来越慢,最终发生阻塞或死锁。

解决方法:

SQL语句中不要使用太复杂的关联多表的查询;使用“执行计划”对SQL语句进行分析,对于有全表扫描的SQL语句,建立相应的索引进行优化。
5.小结
总体上来说,产生内存溢出与锁表都是由于代码写的不好造成的,因此提高代码的质量是最根本的解决办法。有的人认为先把功能实现,有BUG时再在测试阶段进 行修正,这种想法是错误的。正如一件产品的质量是在生产制造的过程中决定的,而不是质量检测时决定的,软件的质量在设计与编码阶段就已经决定了,测试只是 对软件质量的一个验证,因为测试不可能找出软件中所有的BUG。

【原文】http://www.jb51.net/article/78089.htm

mysql数据库死锁的产生原因及解决办法的更多相关文章

  1. mysql保存中文乱码的原因和解决办法

    当你遇到这个mysql保存中文乱码问题的时候,期待找到mysql保存中文乱码的原因和解决办法这样一篇能解决问题的文章是多么激动人心.    也许30%的程序员会选择自己百度,结果发现网友已经贴了很多类 ...

  2. Oracle死锁产生的原因和解决办法

    如果有两个会话,每个会话都持有另一个会话想要的资源,此时就会发生死锁.用下面实验来说明死锁的产生原因和解决办法.SESSION1:SQL> create table t2 as select * ...

  3. 远程连接mysql数据库提示:ERROR 1130的解决办法

    From: http://blog.sina.com.cn/s/blog_716844910100welz.html 在linux下使用mysql客户端连接远程mysql服务器报错: [root@Se ...

  4. 在LINUX系统中MySQL数据库区分表名的大小写--解决办法

    因为linux下mysql默认是要区分表名大小写的.mysql是否区分大小写设置是由参数lower_case_table_names决定的, 其中:1)lower_case_table_names = ...

  5. Mysql 数据库锁表的原因和解决方法

    摘自: https://www.csdn.net/gather_2f/MtTaIgxsMTM5NC1ibG9n.html 锁表的原因:当多个连接(数据库连接)同时对一个表的数据进行更新操作,那么速度将 ...

  6. MySql数据库存储emoji表情报错解决办法

    异常:java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x94' for column 'name' at row 1 解决: ...

  7. MYSQL数据库无法使用IP地址访问的解决办法

    1.在运行中输入CMD,确定,进入文本方式. 2.输入mysql -h localhost -u root -p 回车,使用ROOT用户登录. 3.输入use mysql; 显示Database ch ...

  8. MySql 数据库导入"Unknown command '\n'."错误解决办法

    原文地址:http://www.cnblogs.com/bingxueme/archive/2012/05/15/2501999.html 在CMD 下 输入: Mysql -u root -p -- ...

  9. wamp server mysql数据库中事件不执行的解决办法

    先看看看event 事件是否开启 直接执行下列语句即可, show variables like '%sche%'; 如没开启,则开启. (需要数据库超级权限) set global event_sc ...

随机推荐

  1. javascript两种声明函数的方式的一次深入解析

    声明函数的方式 javascript有两种声明函数的方式,一个是函数表达式定义函数,也就是我们说的匿名函数方式,一个是函数语句定义函数,下面看代码: /*方式一*/ var FUNCTION_NAME ...

  2. TinySpring分析二

    step5 看完了前面的几步,到现在我们必然要想到的问题就是,数据要是放在xml中怎么读? 其实按照正常思维一步一步来,从xml中读数据和之前手工配进去并没有什么大的区别,只要读出来就OK了. 先看测 ...

  3. Netflix Recommendations

    by Xavier Amatriain and Justin Basilico (Personalization Science and Engineering) In part one of thi ...

  4. java数据类型易错点简单总结,欢迎大神前辈补充!谢谢

    数据类型那这边看似简单,花了我很长时间也就是才练到几成"功力"吧.还希望路过的大神在下面补充,菜鸟的我深受感谢! 首先看两个思考题 思考题1:请问下面这个有没有问题 double ...

  5. Cocoa练习01:一个简单的Todo list程序

    写一个简单的todo list程序,界面如下图: 在TextField区域输入文字,点击Add按钮会将文字显示在下面的TableView列表中.TableView列表有2列,第一列是文字的输入时间:第 ...

  6. LeetCode之旅(21)-Swap Nodes in Pairs

    题目: Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1-> ...

  7. linux中syscall调用号查看

    可以用locate查找: locate unistd_32 //或者 locate unistd_64 以下是本猫在ubuntu下返回的结果: /usr/src/linux-headers-3.16. ...

  8. linux系统安装mysql数据库

    1.首先关闭linux的防火墙,执行命令 chkconfig iptables off 2.从mysql官网上下载自己适合的mysql版本https://dev.mysql.com/downloads ...

  9. Collections模块下的Counter

    class Counter(dict) 这个类是dict的子类,对哈希类型的项进行计数,元素被存储为字典的键,他们的计数将作为字典的键值. 主要介绍两个方法: 1.初始化方法:__init__(*ar ...

  10. 视频压缩:I帧、P帧、B帧

    /*************************************************************************************************** ...