Mysql 行级锁的使用及死锁的预防方案_Mysql

一、前言

    mysql的InnoDB,支持事务和行级锁,可以使用行锁来处理用户提现等业务。使用mysql锁的时候有时候会出现死锁,要做好死锁的预防。

二、MySQL行级锁

    行级锁又分共享锁和排他锁。

    共享锁:

      名词解释:共享锁又叫做读锁,所有的事务只能对其进行读操作不能写操作,加上共享锁后其他事务不能再加排他锁了只能加行级锁。

      用法:

SELECT `id` FROM table WHERE id in(1,2)  LOCK IN SHARE MODE 

结果集的数据都会加共享锁

    排他锁:

      名词解释:若某个事物对某一行加上了排他锁,只能这个事务对其进行读写,其他事务不能对其进行加任何锁,其他进程可以读取,不能进行写操作,需等待其释放。

      用法:

SELECT `id` FROM mk_user WHERE id=1 FOR UPDATE

三、实例应用

<?php
  $uid=$_SESSION['uid'];
  //开启事务
  sql:begin
  //开启行级锁的排他锁
  sql:SELECT `coin` FROM user WHERE id=$uid FOR UPDATE
  //扣除用户账户钱币
  $res=update user set coin=coin-value where id=1;
  if($res){
   //将用户的提现信息添加到提现表
   sql:insert into user values(null,"{$uid}",value);
   //判断添加结果
   if(add_cash_result){
    sql:commit
   }else{
    sql:rollback
   }
  }else{
   sql:rollback;
  }

    其实步骤不复杂,就是开启事务判断各个结果为真就提交为假就回滚。单个排他锁没有什么问题,当一个表关联到多个排他锁的时候要注意防止发生死锁。

四、死锁

    `id`  主键索引

    `name` index 索引

    `age`  普通字段

    死锁产生的根本原因是两个以上的进程都要求对方释放资源,以至于进程都一直等待。在代码上是因为两个或者以上的事务都要求另一个释放资源。

    死锁产生的四个必要条件:互斥条件、环路条件、请求保持、不可剥夺,缺一不可,相对应的只要破坏其中一种条件死锁就不会产生。

    例如下面两条语句 第一条语句会优先使用`name`索引,因为name不是主键索引,还会用到主键索引

    第二条语句是首先使用主键索引,再使用name索引 如果两条语句同时执行,第一条语句执行了name索引等待第二条释放主键索引,第二条执行了主键索引等待第一条的name索引,这样就造成了死锁。

    解决方法:改造第一条语句 使其根据主键值进行更新

#①
update mk_user set name ='1' where `name`='idis12';
#②
update mk_user set name='12' where id=12;
//改造后
update mk_user set name='1' where id=(select id from mk_user where name='idis12' );

以上所述是小编给大家介绍的Mysql 行级锁的使用及死锁的预防解决方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索mysql
, 死锁
, 使用
行级锁
mysql 行级锁 死锁、mysql 行级锁、mysql 行级锁 解锁、mysql innodb 行级锁、mysql 行级锁 表级锁,以便于您获取更多的相关知识。

时间: 2024-12-31 02:42:42

Mysql 行级锁的使用及死锁的预防方案_Mysql的相关文章

MySQL行级锁、表级锁、页级锁详细介绍_Mysql

页级:引擎 BDB.表级:引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行行级:引擎 INNODB , 单独的一行记录加锁 表级,直接锁定整张表,在你锁定期间,其它进程无法对该表进行写操作.如果你是写锁,则其它进程则读也不允许行级,,仅对指定的记录进行加锁,这样其它进程还是可以对同一个表中的其它记录进行操作.页级,表级锁速度快,但冲突多,行级冲突少,但速度慢.所以取了折衷的页级,一次锁定相邻的一组记录. MySQL 5.1支持对MyISAM和MEMORY表进行表级锁定,对BDB表进行

MySQL中的行级锁、表级锁、页级锁_Mysql

在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎).表级锁(MYISAM引擎)和页级锁(BDB引擎 ). 一.行级锁 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁.行级锁能大大减少数据库操作的冲突.其加锁粒度最小,但加锁的开销也最大.行级锁分为共享锁 和 排他锁. 特点 开销大,加锁慢:会出现死锁:锁定粒度最小,发生锁冲突的概率最低,并发度也

MySQL中的行级锁,表级锁,页级锁

在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 在数据库的DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎).表级锁(MYISAM引擎)和页级锁(BDB引擎 ). 行级锁 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁.行级锁能大大减少数据库操作的冲突.其加锁粒度最小,但加锁的开销也最大.行级锁分为共享锁和排它锁(MySQL中的共享锁与排他锁) 特点 开销大,加锁慢:会出现死锁:锁定粒度最小,

浅谈Oracle的行级锁

㈠ 单实例Oracle locking机制 locking机制的三大组成部分: ① resource structure Oracle对于每个需要"并发访问"的资源,都在SGA中用一个数据结构来描述它 这个结构叫resource structure 这个数据结构有三个成员:owner.waiter和converter 这是3个指针 指向由lock structure组成的链表的指针 其中,converter和waiter有些区别: 如果某个操作先后需要两种不同模式的锁,比如,先S,后X

SqlServer:行级锁问题

问题描述 刚开始研究SQL锁的问题,现在遇到了两个麻烦:一.在写SP时,设置的TimeOut无效,如果事务没有commit的话,即使超过TimeOut的时间,SP还是不能中断.是不是我哪里弄错了?是不是TimeOut不是这样子理解的?能不能给个实际的例子?网上的那些就算了,看了半天,还是不行二.我一旦锁定一行,如:UPDATEBSN_OrderWITH(ROWLOCK)SETDataSt='N'WHEREBSN_OrderSq=@OrderSq;在这行未释放之前,别的页面在访问这张资料表的时候,

Oracle行级锁的特殊用法简析_oracle

Oracle有许多的锁,各种锁的效用是不一样的.下面重点介绍Oracle行级锁,Oracle行级锁只对用户正在访问的行进行锁定.可以更好的保证数据的安全性. 如果该用户正在修改某行,那么其他用户就可以更新同一表中该行之外的数据. Oracle行级锁是一种排他锁,防止其他事务修改此行,但是不会阻止读取此行的操作. 在使用INSERT.UPDATE.DELETE 和SELECT-FOR UPDATE 等 语句时,Oracle会自动应用Oracle行级锁行级锁锁定.SELECT...FOR UPDAT

Oracle 数据库针对表主键列并发导致行级锁简单演示_oracle

本文内容 •软件环境 •简单演示 Oracle 数据库并发导致行级锁 本文简单演示针对表主键并发导致的行级锁.并发是两个以上的用户对同样的数据进行修改(包括插入.删除和修改).锁的产生是因为并发.没有并发,就没有锁.并发的产生是因为系统需要,系统需要是因为用户需要. 软件环境 -------------------------------------------------------------------------------- •Windows 2003 Server •Oracle 1

请教下关于oracle行级锁的问题

问题描述 我用asp.NET写了一个webservice的接口,大概代码如下log.Info("----------------------------");log.Info("获取余额中...");DataSetdsBalance=GetDataset(string.Format("selectbalancefromINTERFACE_USERwhereusercode='{0}'forupdate",userCode));if(dsBalan

MySQL中由load data语句引起死锁的解决案例_Mysql

一个线上项目报的死锁,简要说明一下产生原因.处理方案和相关的一些点. 1.背景 这是一个类似数据分析的项目,数据完全通过LOAD DATA语句导入一个InnoDB表中.为方便描述,表结构简化为如下: Create table tb(id int primary key auto_increment, c int not null) engine=innodb; 导入数据的语句对应为 Load data infile 'data1.csv' into table tb; Load data inf