mysql锁

MySQL乐观锁总结和实践

大城市里の小女人 提交于 2019-11-29 13:15:29
谈到了MySQL悲观锁,但是悲观锁并不是适用于任何场景,它也有它存在的一些不足,因为 悲观锁大多数情况下依靠数据库的锁机制实现 ,以保证操作最大程度的独占性。 如果加锁的时间过长,其他用户长时间无法访问,影响了程序的并发访问性,同时这样对数据库性能开销影响也很大 ,特别是对长事务而言,这样的开销往往无法承受。所以与悲观锁相对的,我们有了乐观锁,具体参见下面介绍: 乐观锁介绍: 乐观锁( Optimistic Locking ) 相对悲观锁而言, 乐观锁假设认为数据一般情况下不会造成冲突 ,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。那么我们如何实现乐观锁呢,一般来说有以下2种方式: 1.使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现 方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录 的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数 据。用下面的一张图来说明: 如上图所示

MySQL详解--锁

旧街凉风 提交于 2019-11-29 09:59:03
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。本章我们着重讨论MySQL锁机制的特点,常见的锁问题,以及解决MySQL锁问题的一些方法或建议。 MySQL锁概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁;InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。 MySQL这3种锁的特性可大致归纳如下。 开销、加锁速度、死锁、粒度、并发性能 l 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。 l 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。 l 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

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

Deadly 提交于 2019-11-29 08:39:47
关于mysql事务行锁for update实现写锁的功能 读后感:用切面编程的理论来讲,数据库的锁对于业务来说是透明的。spring的事务管理代码,业务逻辑代码,表锁,应该是三个不同的设计层面。 在电子商务里,经常会出现库存数量少,购买的人又特别多,大并发情况下如何确保商品数量不会被多次购买. 其实很简单,利用事务+for update就可以解决. 我们都知道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的一致性 来源: CSDN 作者: liangdu_Zuker 链接: https://blog.csdn.net

MySQL各类SQL语句的加锁机制

做~自己de王妃 提交于 2019-11-29 08:19:27
官网参考: https://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html MySQL把读操作分为两大类:锁定读和非锁定读(即locking read和nonlocking read),所谓非锁定读就是不对表添加事务锁的读操作,如Repeatable Read和Read Committed隔离级别下的select语句(可能脏读也算?)。MySQL的一致性非锁定读是通过MVCC机制实现的。锁定读是指添加事务锁的读操作,例如select for update和select lock in share mode语句。 关于MySQL的锁机制和事务隔离级别,参考以下两篇博客: http://www.cnblogs.com/leohahah/p/8862216.html http://www.cnblogs.com/leohahah/p/8857124.html 第一部分:概述 锁定读、update和delete,这些操作通常会在扫描到的索引记录上添加record locks,InnoDB不关心这些行是否会被where条件过滤,因为InnoDB不记得具体的where条件,它只知道哪个索引范围被扫描过。 这些锁定添加的锁通常是next-key lock,这种锁既锁定扫描到的索引记录,也锁定索引间的gap。不过gap锁可以被显示的禁用

MySQL innodb中各种SQL语句加锁分析

江枫思渺然 提交于 2019-11-29 08:16:55
Locking read( SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE ), UPDATE 以及 DELETE 语句通常会在他扫描的索引所有范围上加锁,忽略没有用到索引的那部分where语句。 举个例子: CREATE TABLE `test` ( `id` int(11) NOT NULL DEFAULT '0', `name` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 select * from test where id > 3 and name <'A' for update; 这条SQL语句的会将所有 id>3 的记录进行加锁,而不是 id>3 and name <'A' 进行加锁,因为name上面没有索引。 如果一个SQL通过二级索引进行扫描,并且在二级索引上设置了一个锁,那么innodb将会在对应的聚簇索引记录上也加上一把锁。 如果一个SQL语句无法通过索引进行 Locking read , UPDATE , DELETE ,那么MySQL将扫描整个表,表中的每一行都将被锁定(在RC级别,通过 semi-consistent read ,能够提前释放不符合条件的记录,在RR级别

Mysql加锁过程详解(8)-理解innodb的锁(record,gap,Next-Key lock)

放肆的年华 提交于 2019-11-29 08:15:48
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select for update/lock in share mode 对事务并发性影响 Mysql加锁过程详解(5)-innodb 多版本并发控制原理详解 Mysql加锁过程详解(6)-数据库隔离级别(1) Mysql加锁过程详解(6)-数据库隔离级别(2)-通过例子理解事务的4种隔离级别 Mysql加锁过程详解(7)-初步理解MySQL的gap锁 Mysql加锁过程详解(8)-理解innodb的锁(record,gap,Next-Key lock) Record lock 单条索引记录上加锁, record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引 ,那么锁住的就是这个隐藏的聚集主键索引。 所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁,这个类似于表锁 ,但原理上和表锁应该是完全不同的。 Gap lock 在索引记录之间的间隙中加锁 ,或者是在某一条索引记录之前或者之后加锁, 并不包括该索引记录本身 。gap lock的机制主要是解决可重复读模式下的幻读问题,关于幻读的演示和gap锁如何解决了幻读

Mysql的select加锁分析

若如初见. 提交于 2019-11-29 08:12:01
引言 大家在面试中有没遇到面试官问你下面六句Sql的区别呢 select * from table where id = ? select * from table where id < ? select * from table where id = ? lock in share mode select * from table where id < ? lock in share mode select * from table where id = ? for update select * from table where id < ? for update 如果你能清楚的说出,这六句sql在不同的事务隔离级别下,是否加锁,加的是共享锁还是排他锁,是否存在间隙锁,那这篇文章就没有看的意义了。 之所以写这篇文章是因为目前为止网上这方面的文章太片面,都只说了一半,且大多没指明隔离级别,以及 where 后跟的是否为索引条件列。在此,我就不一一列举那些有误的文章了,大家可以自行百度一下,大多都是讲不清楚。 OK,要回答这个问题,先问自己三个问题 当前事务隔离级别是什么 id列是否存在索引 如果存在索引是聚簇索引还是非聚簇索引呢? OK,开始回答 正文 本文假定读者,看过我的 《MySQL(Innodb)索引的原理》 。如果没看过,额,你记得三句话吧 innodb一定存在聚簇索引

MySQL间隙锁问题

馋奶兔 提交于 2019-11-29 08:02:44
  间隙锁(Gap Lock):锁加在不存在的空闲空间,可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间。   最近用户反馈说系统老是出现insert时,等待超时了,最后发现是insert间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围。间隙锁的主要作用是为了防止出现幻读,但是它会把锁定范围扩大,有时候也会给我们带来麻烦,我们就遇到了。 在数据库参数中, 控制间隙锁的参数是:   innodb_locks_unsafe_for_binlog,这个参数默认值是OFF, 也就是启用间隙锁, 他是一个bool值, 当值为true时表示disable间隙锁。   那为了防止间隙锁是不是直接将innodb_locaks_unsafe_for_binlog设置为true就可以了呢? 不一定!而且这个参数会影响到主从复制及灾难恢复, 这个方法还尚待商量。   间隙锁的出现主要集中在同一个事务中先delete后 insert的情况下, 当我们通过一个参数去删除一条记录的时候, 如果参数在数据库中存在,那么这个时候产生的是普通行锁,锁住这个记录, 然后删除, 然后释放锁。如果这条记录不存在,问题就来了, 数据库会扫描索引,发现这个记录不存在, 这个时候的delete语句获取到的就是一个间隙锁

mysql事务和锁

孤街醉人 提交于 2019-11-29 02:41:44
尝试进行归纳总结事务和锁的一些思考. 数据库是什么? 保存数据的地方. 为什么保存数据要用数据库呢? 我直接把数据放文件里, 不也一样吗? 比如我自己序列化json文件保存成txt文件成不? 也行, 但是就不方便检索, 之类的. 数据库就方便检索了呀, 数据库相比文件系统有4个特点: A - 原子性 C - 一致性 I - 隔离性 D - 持久性 这里只说锁, 锁是用来保证隔离性的. 隔离性是啥? 比如, 我现在自己实现了一个不怎么完善的数据库, 只是按SQL标准实现了增删改查等命令, 但是操作的数据是直接落实到系统的文件上的. 同时, 要知道SQL标准也规定了4种数据库事务隔离级别, 别急, 我们这个不完善的数据库没有实现事务隔离级别, 也没有实现任何锁, 仅仅是我们知道有这么个东西而已, 暂时不打算去实现它^_^ 虽然我们没有实现它, 但还是可以从事务的角度来进行一下思考, 也就是说我们假想事务这么个东西, 可以启动事务, 提交事务和回滚事务. 假设两个事务--A, B, 说明以下几种存在的问题: 脏读 - A事务启动, 先读取一行, 值为1, 还没提交, B事务启动, 修改了A刚刚读取的那一行, 修改为2, 注意, 没有锁, 虽然在我们的想像中, B还没有提交, 但是anyway, B就是直接就把修改写到文件里了, 然后A再读取这一行, 值是2.

MySQL中的锁

孤街醉人 提交于 2019-11-29 02:02:16
MySQL中的锁 https://www.cnblogs.com/chenqionghe/p/4845693.html 锁是计算机协调多个进程或纯线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所在有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。 概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。 MySQL大致可归纳为以下3种锁: 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般 表级锁 MySQL表级锁有两种模式:表共享锁(Table Read Lock)和表独占写锁(Table Write Lock) 对MyISAM的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求 对MyISAM的写操作,则会阻塞其他用户对同一表的读和写操作 MyISAM表的读操作和写操作之间,以及写操作之间是串行的