关于mysql事务行锁for update实现写锁的功能

 例子1:

在电子商务里,经常会出现库存数量少,购买的人又特别多,大并发情况下如何确保商品数量不会被多次购买.

其实很简单,利用事务+for update就可以解决. (for update仅仅适用于InnoDB)

我们都知道for update实际上是共享锁,是可以被读取的.但是如何在执行时,不被读取呢.

简单来说:假设现在库存为1,现在有A和B同时购买

先开启一个事务

begin;

select stock from good where id=1 for update;//查询good表某个商品中stock的数量

查出来后,在程序里在判断这个stock是否为0(你用什么语言,不关我事)

最后在执行

update good set stock=stock-1 where id=1

最后在

commit

但是这个时候B也是select stock from good where id=1 for update;注意:for update不能省略..这个时候会出现被锁住,无法被读取.

所以这就能够保证了商品剩余数量为1的一致性.

 

例子2:

由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例) ,否则MySQL将会执行Table Lock (将整个资料表单给锁住)。
举个例子:
假设有个表单products ,里面有id跟name二个栏位,id是主键。
例1: (明确指定主键,并且有此笔资料,row lock)
SELECT * FROM products WHERE id=‘3‘ FOR UPDATE;
SELECT * FROM products WHERE id=‘3‘ and type=1 FOR UPDATE;

例2: (明确指定主键,若查无此笔资料,无lock)
SELECT * FROM products WHERE id=‘-1‘ FOR UPDATE;

例2: (无主键,table lock)
SELECT * FROM products WHERE name=‘Mouse‘ FOR UPDATE;

例3: (主键不明确,table lock)
SELECT * FROM products WHERE id<>‘3‘ FOR UPDATE;

例4: (主键不明确,table lock)
SELECT * FROM products WHERE id LIKE ‘3‘ FOR UPDATE;

注1: FOR UPDATE仅适用于InnoDB,且必须在交易区块(BEGIN/COMMIT)中才能生效。
注2: 要测试锁定的状况,可以利用MySQL的Command Mode ,开二个视窗来做测试。

在MySql 5.0中测试确实是这样的
另外:MyAsim 只支持表级锁,InnerDB支持行级锁
添加了(行级锁/表级锁)锁的数据不能被其它事务再锁定,也不被其它事务修改(修改、删除)
是表级锁时,不管是否查询到记录,都会锁定表

此外,如果A与B都对表id进行查询但查询不到记录,则A与B在查询上不会进行row锁,但A与B都会获取排它锁,此时A再插入一条记录的话则会因为B已经有锁而处于等待中,此时B再插入一条同样的数据则会抛出Deadlock found when trying to get lock; try restarting transaction然后释放锁,此时A就获得了锁而插入成功

上面介绍过SELECT ... FOR UPDATE 的用法,不过锁定(Lock)的数据是判别就得要注意一下了。由于InnoDB 预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则mysql 将会执行Table Lock (将整个数据表单给锁住)。

注意:之前orcale中使用过nowait关键字,以为在mySQL中也可以,但是结果却不是这样的。原因是:目前builtin版本的innodb不支持nowait句法的

时间: 2024-10-10 08:26:02

关于mysql事务行锁for update实现写锁的功能的相关文章

Mysql InnoDB行锁实现方式

InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁! 在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能.下面通过一些实际例子来加以说明. (1)在不通过索引条件查询的时候,InnoDB确实使用的是表锁,而不是行锁. 在如表20-9所示的例子中,开始

Mysql InnoDB行锁实现方式(转)

Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁! 在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能.下面通过一些实际例子来加以说明. (1)在不通过索引条件查询的时候,InnoDB确实使用的是表锁,而不是行

MySQL的行锁

概述 MySQL中的行所是基于索引的,行锁是锁定在索引上,所以如果某个字段没有索引,是无法上行锁的. 本文主要是实施验证的过程. 1.使用Innodb引擎建表 mysql> create table innodb( -> id int, -> name varchar(20), -> city varchar(20) -> ) engine innodb default charset utf8 -> ; Query OK, 0 rows affected (0.01

mysql事务和锁InnoDB(转)

背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个死锁场景,了解死锁产生的原因. 注:MySQL是一个支持插件式存储引擎的数据库系统.本文下面的所有介绍

mysql事务和锁InnoDB

背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个死锁场景,了解死锁产生的原因. 注:MySQL是一个支持插件式存储引擎的数据库系统.本文下面的所有介绍

Mysql 事务与锁机制

一. 事务四要素 数据库事务正确执行的四个基本要素包括原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability),简称ACID.目前要实现ACID主要有两种方式:一种是Write ahead logging,也就是日志式的方式(现代数据库均基于这种方式):另一种是Shadow paging. 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节.事务在执行过程中发生错误,会被回滚(Rollback)

mysql事务与锁

事务acid原则 原子性 隔离性 一致性 持久性 事务的概念 把需要保证原子性.隔离性.一致性和持久性的一个或者多个数据库操作称为事务. 事务的使用 语法 begin;//开启一个事务 some sql;//需要执行的语句 savepoint bussiness1;//事务保存点 some sql; roll back to bussiness1;//回滚 commit;//提交事务 rollback;//如果需要手动回滚的话在提交之前删除这句 事务的自动提交 通常情况下mysql默认自动提交事

MySQL事务和锁 (四)

一 .事务 1.1 事务的概念 mysql把多条写操作视为一个整体去执行,要么全部成功,要么全部失败,我们把mysql的这种处理叫做事务.(“多条”很好理解就是至少两条sql语句,“写操作”就是指对msyql内容修改的操作(insert.update.delete)). 1.2事务的特性 原子性: 确保工作单元内的所有操作都成功完成,否则事务将被中止在故障点,和以前的操作将回滚到以前的状态. 一致性: 确保数据库正确地改变状态后,成功提交的事务. 隔离性: 使事务操作彼此独立的和透明的. 持久性

MySQL事务、锁

事务描述: 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务.事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行.事务它还可以用来管理DDL.DML.DCL操作,比如 insert,update,delete 语句.一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性): 构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行 Consistency(稳定性.一致性):      数据库在事务执