mysql 事务 for update_mysql事务,select for update,及数据的一致性处理
在MySQL的InnoDB中,预设的Tansaction isolation level 为REPEATABLE READ(可重读)
在SELECT 的读取锁定主要分为两种方式:
SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE
这两种方式在事务(Transaction) 进行当中SELECT 到同一个数据表时,都必须等待其它事务数据被提交(Commit)后才会执行。
而主要的不同在于LOCK IN SHARE MODE 在有一方事务要Update 同一个表单时很容易造成死锁。
简单的说,如果SELECT 后面若要UPDATE 同一个表单,最好使用SELECT ... UPDATE。
举个例子:
假设商品表单products 内有一个存放商品数量的quantity ,在订单成立之前必须先确定quantity 商品数量是否足够(quantity>0) ,然后才把数量更新为1。代码如下:
SELECT quantity FROM products WHERE id=3; UPDATE products SET quantity = 1 WHERE id=3;
为什么不安全呢?
少量的状况下或许不会有问题,但是大量的数据存取「铁定」会出问题。如果我们需要在quantity>0 的情况下才能扣库存,假设程序在第一行SELECT 读到的quantity 是2 ,看起来数字没有错,但
是当MySQL 正准备要UPDATE 的时候,可能已经有人把库存扣成0 了,但是程序却浑然不知,将错就错的UPDATE 下去了。因此必须透过的事务机制来确保读取及提交的数据都是正确的。
于是我们在MySQL 就可以这样测试,代码如下:
SET AUTOCOMMIT=0; BEGIN WORK; SELECT quantity FROM products WHERE id=3 FOR UPDATE;
此时products 数据中id=3 的数据被锁住(注3),其它事务必须等待此次事务 提交后才能执行
SELECT * FROM products WHERE id=3 FOR UPDATE 如此可以确保quantity 在别的事务读到的数字是正确的。
UPDATE products SET quantity = '1' WHERE id=3 ; COMMIT WORK;
提交(Commit)写入数据库,products 解锁。
注1: BEGIN/COMMIT 为事务的起始及结束点,可使用二个以上的MySQL Command 视窗来交互观察锁定的状况。
注2: 在事务进行当中,只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据时会等待其它事务结束后才执行,一般SELECT ... 则不受此影响。
注3: 由于InnoDB 预设为Row-level Lock,数据列的锁定可参考这篇。
注4: InnoDB 表单尽量不要使用LOCK TABLES 指令,若情非得已要使用,请先看官方对于InnoDB 使用LOCK TABLES 的说明,以免造成系统经常发生死锁。
MySQL SELECT ... FOR UPDATE 的Row Lock 与Table Lock
上面介绍过SELECT ... FOR UPDATE 的用法,不过锁定(Lock)的数据是判别就得要注意一下了。由于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;
例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;
乐观所和悲观锁策略
悲观锁:在读取数据时锁住那几行,其他对这几行的更新需要等到悲观锁结束时才能继续 。
乐观所:读取数据时不锁,更新时检查是否数据已经被更新过,如果是则取消当前更新,一般在悲观锁的等待时间过长而不能接受时我们才会选择乐观锁。
mysql 事务 for update_mysql事务,select for update,及数据的一致性处理相关推荐
- MySql事务select for update及数据的一致性处理讲解
MySQL中的事务,默认是自动提交的,即autocommit = 1: 但是这样的话,在某些情形中就会出现问题:比如: 如果你想一次性插入了1000条数据,mysql会commit1000次的, 如果 ...
- mysql事务实现数据更新_MySql事务select for update及数据的一致性处理讲解
MySQL中的事务,默认是自动提交的,即autocommit = 1: 但是这样的话,在某些情形中就会出现问题:比如: 如果你想一次性插入了1000条数据,mysql会commit1000次的, 如果 ...
- mysql事务模式怎么查_Mysql InnoDB中的查询事务模式与锁定select ..for update
在 InnoDB 的行锁中使用所谓的 next-key locking.这就意味着,除了索引记录外,InnoDB 还可以锁定该索引记录前部"间隙" ('gap') 以阻塞其它用户在 ...
- java mysql实现原理_MySQL事务实现原理
MySQL事务隔离级别的实现原理 知识储备 只有InnoDB支持事务,所以这里说的事务隔离级别是指InnoDB下的事务隔离级别 隔离级别 读未提交:一个事务可以读取到另一个事务未提交的修改.这会带来脏 ...
- 【MySQL】MySQL的四种事务隔离级别
[MySQL]MySQL的四种事务隔离级别 本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事 ...
- MySQL事务原理之事务概述和隔离级别
MySQL事务概述和隔离级别 事务 事务的特征 事务的控制语句 事务的生命周期 事务执行过程 ACID特性 原子性(A) 一致性(C) 隔离性(I) 持久性(D) 隔离级别 命令 不同隔离级别并发异常 ...
- rabbit和mysql事务_分布式事务原理及SpringBoot整合RabbitMQ实现可靠事件,TCC事务模型及接口幂等性...
分布式事务 我们知道在单数据库系统中,实现数据的一致性,通过数据库的事务来处理比较简单.在微服务或分布式系统中,各个独立的服务都会有自己的数据库,而不是在同一个数据库中,所以当一组事务(如商品交易中, ...
- select for update加了行锁还是表锁?
前言 大家,我是田螺. 最近在开发需求的时候,用到了select......for update.在代码评审的时候,一位同事说 ,唯一索引+一个非索引字段,是否可能会锁全表呢?本文田螺哥将通过9个实验 ...
- 事务并发、事务隔离级别
2019独角兽企业重金招聘Python工程师标准>>> 并发问题可归纳为以下几类: A.丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖(A和B事务并发执行,A事务执行更新后 ...
最新文章
- Oracle 11g Release 1 (11.1) 查询优化器的访问路径
- VS2013运行报错error C4996: 'scanf': This function or variable may be unsafe.
- C语言转移表之加减乘除无限进化版
- Koa框架——coderhub实战
- python中matlab函数图像处理,MATLAB图像处理--同态滤波(代码及示例)
- linux下的5个查找命令
- Pannellum:详解利用Pannellum实现Web三维全景功能
- linux硬盘打开ncq,linux下如何开启ncq
- 被王思聪抽奖炸了的微博,究竟是算法背锅还是自己作死?
- 6.形容词性物主代词用法
- 百利药业IPO过会:扣非后年亏1.5亿 奥博资本是股东
- 浪潮存储加速国产替代
- 认知入门之经济学通识
- 成也苹果败也苹果,曾经女首富身价缩水一半
- 你知道我们常说的“向前兼容”和“向后兼容”都是什么意思吗?
- 22款受欢迎的计算机取证工具
- IDM下载器的安装与使用
- (一)因式分解机(Factorization Machine,FM)原理及实践
- MFC WebBrowser获取网面完整源码 WebBrowser获取网面完整HTML
- 解决驱动器中没有磁盘的问题
热门文章
- python xpath提取转码_python-xpath获取html文档的部分内容
- 嵌入式与单片机之间的关系是什么?
- 摊牌了,我靠它们成功实现了AI零基础入门到进阶!
- 为什么嵌入式工程师会对8位MCU有误解?
- android sqlite更改数据,更新现有的sqlite数据库中的列,但没有任何更改android
- Linux 网页挂马实验,网页挂马详细教程
- 判断sem信号量为零_Linux线程同步(互斥量、信号量、条件变量、生产消费者模型)...
- mfc 算方差函数_什么影响了你的工资?方差分析告诉你
- python源码编译安装 gb18030_源代码编译安装Python3.5.2
- 绵阳python培训_《绵》原文及翻译海绵翻译