innodb 悲观锁,乐观锁
转 http://www.cnblogs.com/chenwenbiao/archive/2012/06/06/2537508.html
CREATE TABLE `products` (
`id` int() NOT NULL AUTO_INCREMENT,
`name` varchar() NOT NULL,
`quantity` int NOT NULL,
`cityid` varchar() DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_of_cityid` (`cityid`,`id`)
) ENGINE=InnoDB; insert into products (name,quantity,cityid) values ('牙刷',, );
insert into products (name,quantity,cityid) values ('大米',,);
insert into products (name,quantity,cityid) values ('豆角',,);
insert into products (name,quantity,cityid) values ('苹果',,);
不安全的做法:
SELECT quantity FROM products WHERE id=3;
UPDATE products SET quantity = quantity -1 WHERE id=3;
第一个访问者 第二个访问者
A)SELECT quantity FROM products WHERE id=3;
C)SELECT quantity FROM products WHERE id=3;
B)UPDATE products SET quantity = quantity -1 WHERE id=3;
D)UPDATE products SET quantity = quantity -1 WHERE id=3;
假设两次访问前quantity数量为10
第一个访问者执行select后,得到 quantit7=10,
第二个访问者到达,由于CPU时间片分配,将控制权给了第二个访问者,通过select,得到quantity=10
再次时间片轮循,第一个访问者执行B SQL后,quantity=9
第二个访问者执行D SQL 后,quantity仍然为9,因为第二个访问者并不知道第一个访问者的存在, 这就出问题了
解决方法
最简单的就是加 悲观锁, 缺点:若锁的时候过长,其他用户无法访问,影响并发性,加锁,会增加额外开销
或者应用层利用乐观锁, 并发大的情况下较好,避免加锁
第一个访问者 第二个访问者
A)SELECT quantity FROM products WHERE id=3 for update;
C)SELECT quantity FROM products WHERE id=3 for update;
B)UPDATE products SET quantity = quantity -1 WHERE id=3;
D)UPDATE products SET quantity = quantity -1 WHERE id=3;
sql执行如下
A窗口

此时,在B窗口,再执行一遍select

被锁住, for update 悲观锁,也称为排他锁,不允许他人读/写
A窗口,执行commit

此时B窗口

即可看见 id=1的记录
另外,当select ... where for update 中的where条件不是主键,哪怕是其他索引时,也会锁表,
A窗口

B窗口

当A窗口,commit后,B窗口者返回数据, 尽管cityid为索引,但也发生了表锁

当为主键时,才行锁
A窗口,不commit

B窗口取数据,马上返回数据

二.乐观锁
在表中加一个列 version, update更新后就加1
在访问前假设 version=10
第一次访问 第二次访问
A) select quantity, version from products;
C) select quantity, version from products;
B) update products set version=version+1,quantity=quantity-1 where version=10 and id=1
D) update products set version=version+1,quantity=quantity-1 where version=10 and id=1
当第一个访问者执行B后,version已由10,变成了11
当第二个访问者执行D后,找不到version=10的记录,影响的记录为0,需要重试几次
innodb 悲观锁,乐观锁的更多相关文章
- Java并发 行级锁/字段锁/表级锁 乐观锁/悲观锁 共享锁/排他锁 死锁
原文地址:https://my.oschina.net/oosc/blog/1620279 前言 锁是防止在两个事务操作同一个数据源(表或行)时交互破坏数据的一种机制. 数据库采用封锁技术保证并发操作 ...
- Hibernate悲观锁/乐观锁
如果需要保证数据访问的排它性,则需对目标数据加"锁",使其无法被其它程序修改 一,悲观锁 对数据被外界(包括本系统当前的其它事务和来自外部系统的事务处理)修改持保守态度,通过数据库 ...
- SQL Server 锁机制 悲观锁 乐观锁 实测解析
先引入一些概念,直接Copy其他Blogs中的,我就不单独写了. 一.为什么会有锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 1.丢失更新 A,B两个用户读同一数据并进行修改,其中 ...
- 最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁
在Java并发场景中,会涉及到各种各样的锁如公平锁,乐观锁,悲观锁等等,这篇文章介绍各种锁的分类: 公平锁/非公平锁 可重入锁 独享锁/共享锁 乐观锁/悲观锁 分段锁 自旋锁 01.乐观锁 vs 悲观 ...
- Java最全锁剖析:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁
乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度,在Java和数据库中都有此概念对应的实际应用. 1.乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会 ...
- Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁
Optimistic concurrency control https://en.wikipedia.org/wiki/Optimistic_concurrency_control Optimist ...
- MySQL/InnoDB中,乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念的理解
文章出处:https://www.souyunku.com/2018/07/30/mysql/?utm_source=tuicool&utm_medium=referral MySQL/Inn ...
- MySQl中隔离级别和悲观锁乐观锁
1.MySql的事物支持 MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关: MyISAM:不支持事务,用于只读程序提高性能 InnoDB:支持ACID事务.行级锁.并发 Ber ...
- 【MySQL】悲观锁&乐观锁
悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍. 悲观锁(Pessimistic Lock) 悲观锁的 ...
随机推荐
- 定时备份服务器数据库(借助windows任务计划以及mysqldump)
最近社区多了,考虑到数据的安全性,要每天备份一次数据库,以防万一: linux目前还不是很了解,先用windows的计划任务吧: 大体思路就是 借用windows的计划任务来执行备份远程数据库到本地: ...
- 去掉iphone手机滑动默认行为
/*去掉iphone手机滑动默认行为*/ $('body').on('touchmove', function (event) { event.preventDefault(); });
- 最简便的清空memcache的方法
如果要清空memcache的items,常用的办法是什么?杀掉重启?如果有n台memcache需要重启怎么办?挨个做一遍? 很简单,假设memcached运行在本地的11211端口,那么跑一下命令行: ...
- 使用rar打包多个文件为exe可执行文件
需求分析:有些机友在刷recovery的时候不知道如何刷入,于是产生写bat脚本和打包为exe可执行文件,只要机友正确安装好驱动后连接手机双击就可以刷入rec了 解决过程: 需要打包的文件 操作过程截 ...
- H264相关代码
H.264格式的视频打包成RTP后进行发送,编译环境为VC6++ #include <stdio.h> #include <stdlib.h> #include <str ...
- 1027 Colors in Mars (20)
#include <stdio.h> #include <map> using namespace std; int main() { int R,G,B,i; map< ...
- Hibernate从入门到精通(二)Hibernate实例演示
上篇Hibernate从入门到精通(一)JDBC简介,我们主要对JDBC进行了简单介绍和使用说明,这次我们做一个Hibernate简单实例,通过这个实例对比Hibernate和JDBC,了解Hiber ...
- 【学习总结】OS X , IOS , IOS SDK , XCode之间的关系
几个基本的概念 : OS X : 属于桌面PC级别(IMac,MacPro等)对应安装的操作系统 IOS : 属于移动设备级别(Iphone,Ipad等)对应安装的操作系统 XCode: 是一个IDE ...
- DateTime.ToString()
/* [y]代表年份,注意是小写的y,大写的Y并不代表年份. [M]表示月份. [d]表示日期,注意D并不代表什么. ...
- 1016: [JSOI2008]最小生成树计数 - BZOJ
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...