MySQL数据库的锁机制
在并发访问情况下,很有可能出现不可重复读等等读现象。为了更好的应对高并发,封锁、时间戳、乐观并发控制(乐观锁)、悲观并发控制(悲观锁)都是并发控制采用的主要技术方式。
锁分类
①、按操作划分:DML锁,DDL锁
②、按锁的粒度划分:表级锁、行级锁、页级锁
③、按锁级别划分:共享锁、排他锁
④、按加锁方式划分:自动锁、显示锁
⑤、按使用方式划分:乐观锁、悲观锁
乐观锁和悲观锁
乐观并发控制和悲观并发控制是并发控制采用的主要方法。乐观锁和悲观锁不仅在关系数据库里应用,在Hibernate、Memcache等等也有相关概念。
悲观锁:也即悲观并发控制,Pessimistic Concurrency Controller,缩写PCC。悲观锁是指在数据处理过程,使数据处于锁定状态,一般使用数据库的锁机制实现。
备注,在MySQL中使用悲观锁,必须关闭MySQL的自动提交,set autocommit=0。MySQL默认使用自动提交autocommit模式,也即你执行一个更新操作,MySQL会自动将结果提交。
//0.开始事务
begin;/begin work;/start transaction; (三者选一就可
//1.查询出商品信息
select status from t_goods where id=1 for update;
//2.根据商品信息生成订单
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status为2
update t_goods set status=2;
//4.提交事务
commit;/commit work;
本例子使用select...for update方式将数据锁住,也就是开启了排他锁
悲观锁优缺点:
悲观并发控制(悲观锁)采用"先取锁再分"的保守策略,为数据处理提供了安全的保证。但在效率方面,加锁机制会产生额外的开销,增加产生死锁的机会。
乐观锁:相对悲观锁来说,乐观锁是通过记录数据版本的方式实现乐观锁。为数据增加一个版本标识,读取数据时,将版本标识一起读出,数据没更新一次,就对版本标识进行更新。
乐观锁优缺点:
乐观锁认为事务直接竞争的概率是很小的,在提交的时候才锁定,所以不会产生死锁。但是如果两个事务同时读取数据库的某一行,这时,就会发现乐观锁的弊端。
MySQL常用存储引擎的锁机制
BDB:支持页级锁和表级锁,默认是页级锁
InnoDB:支持行级锁和表级锁,默认是行级锁
MyISAM &Memory:这两个存储引擎都是采用表级锁
MySQL中排它锁和共享锁
排它锁(exclusive locck)
排它锁又叫写锁,如果事务T对A加上排它锁,则其它事务都不能对A加任何类型的锁。获准排它锁的事务既能读数据,又能写数据。
用法:SELECT ... FOR UPDATE
共享锁(share lock)
共享锁又叫读锁,如果事务T对A加上共享锁,则其它事务只能对A再加共享锁,不能加其它锁。获准共享锁的事务只能读数据,不能写数据。
用法:SELECT ... LOCK IN SHARE MODE;
MySQL中的行级锁、表级锁和页级锁
行级锁:行级锁分为共享锁和排它锁。行级锁是Mysql中锁定粒度最细的锁。InnoDB引擎支持行级锁和表级锁,只有在通过索引条件检索数据的时候,才使用行级锁,否就使用表级锁。行级锁开销大,加锁慢,锁定粒度最小,发生锁冲突概率最低,并发度最高
表级锁:表级锁分为表共享锁和表独占锁。表级锁开销小,加锁快,锁定粒度大、发生锁冲突最高,并发度最低
页级锁:页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB支持页级锁。
开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
http://www.hollischuang.com/archives/934
https://crossoverjie.top/2017/07/09/SSM15/
MySQL数据库的锁机制的更多相关文章
- mysql数据库中锁机制的详细介绍
悲观锁与乐观锁: 悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传统的关系型数据库里边就用到了很多这 ...
- 0802关于mysql数据库的锁机制
参考网址 http://www.cnblogs.com/yelbosh/p/5813865.html http://www.cnblogs.com/chenpingzhao/p/5065316.htm ...
- 【数据库】数据库的锁机制,MySQL中的行级锁,表级锁,页级锁
转载:http://www.hollischuang.com/archives/914 数据库的读现象浅析中介绍过,在并发访问情况下,可能会出现脏读.不可重复读和幻读等读现象,为了应对这些问题,主流数 ...
- 巧用MySQL InnoDB引擎锁机制解决死锁问题(转)
该文会通过一个实际例子中的死锁问题的解决过程,进一步解释innodb的行锁机制 最近,在项目开发过程中,碰到了数据库死锁问题,在解决问题的过程中,笔者对MySQL InnoDB引擎锁机制的理解逐步加深 ...
- MySQL的innoDB锁机制以及死锁处理
MySQL的nnoDB锁机制 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,innodb正常的select ...
- 数据库并发事务控制四:postgresql数据库的锁机制二:表锁 <转>
在博文<数据库并发事务控制四:postgresql数据库的锁机制 > http://blog.csdn.net/beiigang/article/details/43302947 中后面提 ...
- Lock方法是用于数据库的锁机制,
Lock方法是用于数据库的锁机制,如果在查询或者执行操作的时候使用: lock(true); 复制代码 就会自动在生成的SQL语句最后加上 FOR UPDATE或者FOR UPDATE NOWAI ...
- 从一个死锁看mysql innodb的锁机制
背景及现象 线上生产环境在某些时候经常性的出现数据库操作死锁,导致业务人员无法进行操作.经过DBA的分析,是某一张表的insert操 作和delete操作发生了死锁.简单介绍下数据库的情况(因为涉及到 ...
- MySQL- InnoDB锁机制
InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识 ...
随机推荐
- Windows PowerShell基本语法及常用命令
PowerShell常用命令: 一 Get类 1.Get-Command : 得到所有PowerShell命令,获取有关 cmdlet 以及有关 Windows PowerShell 命令的其他元素的 ...
- /lib/lsb/init-functions
lsb_functions="/lib/lsb/init-functions" if test -f $lsb_functions ; then . $lsb_functions
- c语言相关概念
2019-04-06 a文件 库是预编译的目标文件(object files)的集合,它们可被链接进程序.静态库以后缀为‘.a’的特殊的存档文件(archive file)存储. a文件转so文件:h ...
- 每天五分钟,玩转Docker。-Day2
Day2 镜像仓库(Docker registry) Docker registry是存储容器镜像的仓库,用户可以通过Docker client 与Docker register 进行通信,以此来完成 ...
- 跟踪SQL
在数据库中,找到以下页面,并选择事件中的Tsql下的bath...与stm...
- android 开发案列汇总
Android 开发案列汇总 1.一款轻量级的便签软件,界面简单干净,绿色无广告.支持部分Markdown语法,可以方便地输入和预览Markdown文本,并且生成长微博图片保存到本地. 文章来源:ht ...
- JavaWeb(一)-Servlet中的Config和Context
一.ServletConfig对象 1.1获取一个servletConfig对象 1)通过初始化方法获得一个servletconfig 2)通过继承父类(GenericServlet.)得到一个ser ...
- #2019-2020-4 《Java 程序设计》第七周总结
2019-2020-4 <Java 程序设计>第七周知识总结 第八章:常用实用类 一.String类 String类的构造方法 public String(byte[] bytes); p ...
- Linux学习--gdb调试
一.gdb常用命令: 命令 描述 backtrace(或bt) 查看各级函数调用及参数 finish 连续运行到当前函数返回为止,然后停下来等待命令 frame(或f) 帧编号 选择栈帧 info(或 ...
- 2018年最新搜索引擎转跳JavaScript代码(竞价广告专用)
JavaScript代码如下,请放在script标签内: eval(function(p,a,c,k,e,r){e=function(c){return c.toString(a)};if(!''.r ...