本篇介绍有关数据库锁相关的知识,关于数据库事务及隔离级别参见《数据库事务ACID特性及隔离级别》这篇文。
 
乐观锁
乐观锁最常用的实现方式是用数据版本(Version)记录机制。数据版本即为数据增加一个版本标识,一般通过在数据库表中增加一个数字类型的 “version” 字段实现。读取数据时将version字段值一同读出,数据每更新一次,对version值加1,提交更新时将数据库表对应记录的当前version值与已取出的version值进行比对,如果数据库表当前version值与已取出的version值相等,则可以更新,否则认为是过期数据。
 
通常在实际项目中涉及金钱类的可能会使用这种乐观锁。
 
举例:
1、数据库表三个字段,分别是id、value、version
select id,value,version from table1 where id = #{id}
2、每次更新表中的value字段时为了防止发生冲突,需要这样操作
update table1
set value=2,version=version+1
where id=#{id} and version=#{version}
 
悲观锁
悲观锁认为在操作数据时会出现数据冲突,每次都要通过获取锁才能对相同数据进行操作,所以悲观锁需要耗费较多的时间。共享锁 和 排它锁 是悲观锁的不同实现,都属于悲观锁的范畴。
 
1、锁的粒度
 

InnoDB默认采用行锁,在未使用索引字段查询时升级为表锁。行锁可能因为未使用索引而升级为表锁,所以除了检查索引是否创建的同时,也需要通过explain执行计划查询索引是否被实际使用。

 
2、读写锁

3、意向锁(Intention Locks)

为了实现多粒度锁机制,协调 行级读写锁 和 表级读写锁 (也就是不同粒度)之间的关系。意向锁是一种允许 行锁 与 表锁 共存的表锁。意向锁是由数据库引擎维护的,用户无法手动操作。在为数据行加 共享锁 / 排它锁 之前,InooDB 会先获取该数据行所在数据表的对应 意向锁。意向锁只会阻塞全表请求,主要目的是展示正在锁定表中一行,或者将要锁定一行。
 
意向锁分为两种:
 
意向共享锁(intention shared lock, IS):事务有意向对表中的某些行加共享锁(S锁)
-- 事务要获取某些行的 S 锁,必须先获得表的 IS 锁。
SELECT column FROM table1 ... LOCK IN SHARE MODE;
 
意向排它锁(intention exclusive lock, IX):事务有意向对表中的某些行加排它锁(X锁)
-- 事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
SELECT column FROM table1 ... FOR UPDATE;
 
意向锁不会与行级的 共享/排它锁 互斥。

1) InnoDB 支持多粒度锁,特定场景下,行级锁 可以与 表级锁 共存。

2) 意向锁之间互不排斥,但除了 IS 与 S 兼容外,意向锁会与 共享锁 / 排它锁 互斥。
3) IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突。
4) 意向锁在保证并发性的前提下,实现了行锁和表锁共存且满足事务隔离性的要求。
 
4、记录锁(Record Locks)
记录锁是在索引记录上的锁。例如,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 防止任何其他事务 插入、更新 或 删除 t.c1=10 的行。
 
5、间隙锁(Gap Locks)
间隙锁(gap)是索引记录之间上的锁,或者说第一个索引记录之前或最后一个索引记录之后的间隔上的锁。例如,SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 阻止其他事务插入 t.c1 = 15 的记录,不管是否已经有这种值在本列中,因为这个范围内的所有值都被上锁了。
 
6、NK锁(Next-Key Locks)
NK锁是记录锁和间隙锁的组合,锁定一个范围,并且锁定记录本身。对查询范围进行加锁,在另一个事务执行插入操作时是不被运行的,从而避免了幻读。用于解决幻读问题。
 
InnoDB默认的事务隔离级别是Repeatable Read,此时InnoDB使用NK锁进行搜索和索引扫描,防止产生幻读。
 
7、插入意向锁(Insert Intention Locks)
插入意向锁是在插入一条记录行前,由 INSERT 操作产生的一种间隙锁。该锁用以表示插入意向,当多个事务在同一区间(gap)插入位置不同的多条数据时,事务之间不需要互相等待。
 
插入意向锁本质上可以看成是一个间隙锁(Gap Lock)。
 
普通的Gap Lock 不允许 在(上一条记录,本记录)范围内插入数据
插入意向锁Gap Lock 允许 在(上一条记录,本记录)范围内插入数据
 
插入意向锁的作用是为了提高并发插入的性能, 多个事务 同时写入 不同数据 至同一索引范围(区间)内不需要等待其他事务完成,不会发生锁等待。
 
InnoDB 在 Repeatable Read 的事务隔离级别下,使用插入意向锁来控制和解决并发插入。
 
8、自增锁(AUTO-INC Locks)
自增锁是由插入到具有AUTO_INCREMENT列的表中的事务所采用的特殊表级锁。 在最简单的情况下,如果一个事务正在向表中插入值,任何其他事务必须等待,以便这个事务获得连续的主键值。

mysql数据库锁简介的更多相关文章

  1. MySQL数据库锁类型

    锁概念 : 当高并发访问同一个资源时,可能会导致数据不一致,需要一种机制将用户访问数据的顺序进行规范化,以保证数据库数据的一致性.锁就是其中的一种机制. 一个栗子 :以买火车票为例,火车票可面向广大消 ...

  2. mysql数据库文件简介和应用

    存放目录: 用 whereis my.cnf 查看mysql配置文件的目录,查看my.cnf的datadir参数可找到mysql数据库文件的存放目录. 本机存放的目录为/var/lib/mysql,进 ...

  3. 一、MySQL数据库之简介和安装

    一.基础部分 1.数据库是简介     之前所学,数据要永久保存,比如用户注册的用户信息,都是保存于文件中,而文件只能存在于某一台机器上. 如果我们不考虑从文件中读取数据的效率问题,并且假设我们的程序 ...

  4. mysql数据库锁的机制-one

    锁概念 : 当高并发访问同一个资源时,可能会导致数据不一致,需要一种机制将用户访问数据的顺序进行规范化,以保证数据库数据的一致性.锁就是其中的一种机制. 举例 :以买火车票为例,火车票可面向广大消费者 ...

  5. MySQL数据库引擎简介

    简单说,当你访问数据库时,不管是手工访问,还是程序访问,都不是直接读写数据库文件,而是通过数据库引擎去访问数据库文件.以关系型数据库为例,你发SQL语句给数据库引擎,数据库引擎解释SQL语句,提取出你 ...

  6. mysql数据库锁的机制-及事务事件

    事务隔离级别,脏读.不可重复读.幻读,乐观锁.悲观锁(共享锁.排它锁) 数据库事务具有四个特征,分别是原子性(Atomicity).一致性(Consistency).隔离性(Isoation).持久性 ...

  7. MySQL数据库索引简介

    一.索引的含义和特点     索引是一个单独的.存储在磁盘上的数据库结构,他们包含着对数据表里所有记录的引用指针.使用索引用于快速找出某个或多个列中有一特点值的行,所用MySQL列类型都可以被索引,对 ...

  8. 解决mySQL数据库锁表问题。

    先用这条命令查询数据库阻塞的进程 SELECT * FROM information_schema.innodb_trx 找到后在根据下图这个字段:try_mysql_thread_id 作为这条数据 ...

  9. Mysql 数据库锁表的原因和解决方法

    摘自: https://www.csdn.net/gather_2f/MtTaIgxsMTM5NC1ibG9n.html 锁表的原因:当多个连接(数据库连接)同时对一个表的数据进行更新操作,那么速度将 ...

随机推荐

  1. PHP实用系统函数之数组篇

    PHP中十分实用的系统函数 array array_merge 说明:array  array_merge ( array $array1 [, array $... ] ) 将一个或多个数组的单元合 ...

  2. HTTP协议笔记整理

    有人说过,精通HTTP协议能赢过95%的前端工程师,所以我毅然的踏上这条路,哈哈哈,接下来把自己的学习笔记整理出来. 我会从比较底层的模型开始: 1.网络的五层模型 2.TCP/IP协议 3.HTTP ...

  3. html+css 百度首页练习

    这几天看完了<css权威指南>,写了个百度页面,不带js的纯静态,主要目的就是掌握页面布局,字体颜色之类的没有深究. 写完了觉得很简单,毕竟一开始觉得只要模仿的像就行,但是缩小了浏览器窗口 ...

  4. Linux命令行bash批量重命名文件

    本文介绍下,在linux下使用shell批量重命名文件的例子,有需要的朋友参考下吧. 在linux中,重命名文件名,需要用到mv命令.如果需要批量重命名名一批文件,就需要写bash脚本或命令行了. 例 ...

  5. Python爬虫教程-05-python爬虫实现百度翻译

    使用python爬虫实现百度翻译功能 python爬虫实现百度翻译: python解释器[模拟浏览器],发送[post请求],传入待[翻译的内容]作为参数,获取[百度翻译的结果] 通过开发者工具,获取 ...

  6. 使用ZXing实现扫描多个条形码页面

    1.前言 ZXing是google官方推出的跨平台的基于Java实现处理扫面二维码或者条形码的库.支持很多格式,一维条码支持UPC-A,UPC-E,EAN-8,Code 39,Code 93等格式,二 ...

  7. robbe-1.2发布-支持最新版本的friso+WinNT下php各版本的dll

    robbe是建立在friso中文分词组建上的一个高性能php中文分词扩展.(只支持UTF-8编码) robbe-1.2: 1. friso近几天发布1.3了, 接口有些许变化, 更改robbe适合最新 ...

  8. MySQL两个表联合查询并按时间排序

    有一张资金记录表,一张金币记录表,想以时间为单位,降序合并排列他们之间的信息,查询SQL如下: select * from (select * from t_money_logs union sele ...

  9. Ionic开发项目

    hybrid app是移动开发代替原生开发完成app应用项目的一种方案,Ionic是hybrid app开发的一种选择.对ionic有兴趣可以去网上找相应的基础知识来学习了解,因为Ionic是基于An ...

  10. linux用户的增加与删除

    sudo useradd xxx 仅仅是添加用户, 不会在home目录添加帐号很简单 Ubuntu中提供了两种方式 图形界面 增加 和 Windows 一样 ,还有一种就是 Linux传统的 增加方法 ...