一、引言                                                                                                                         

MySQL引擎默认的锁级别:

MyISAM和MEMORY采用表级锁(table-level locking)。

BDB采用页面锁(page-level locking)或表级锁,默认为页面锁。

InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁。

二、Innodb引擎中的行锁与表锁                                                                                    

在Innodb引擎中既支持行锁也支持表锁,那么什么时候会锁住整张表,什么时候或只锁住一行呢?

InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,Oracle者是通过在数据块中对相应数据行加锁来实现的。

InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。

行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁。

行级锁的缺点是:如果并发请求大量的锁资源,所以速度慢,内存消耗大。

1、行级锁与死锁

MyISAM中是不会产生死锁的,因为MyISAM总是一次性获得所需的全部锁,要么全部满足,要么全部等待。

在InnoDB中,锁是逐步获得的,就造成了死锁的可能。

在MySQL中,行级锁并不是直接锁记录,而是锁索引。

索引分为主键索引和非主键索引两种:

如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;

如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。

在UPDATE、DELETE操作时,MySQL不仅锁定WHERE条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的next-key locking。

当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引。另一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。

发生死锁后,InnoDB一般都可以检测到,并使一个事务释放锁回退,另一个获取锁完成事务。

有多种方法可以避免死锁,我们来介绍常见的三种

  • 如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。
  • 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
  • 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;

2、表锁

表锁分为表共享读锁(共享锁)与表独占写锁(排他锁)

  • 共享锁(Share Lock)又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。

如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。

使用:SELECT ... LOCK IN SHARE MODE;

在查询语句后面增加LOCK IN SHARE MODE, Mysql会对查询结果中的每行都加共享锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读 取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。

  • 排他锁(exclusive Lock)又称写锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的锁。获准排他锁的事务既能读数据,又能修改数据。

使用:SELECT ... FOR UPDATE;

在查询语句后面增加FOR UPDATE, Mysql会对查询结果中的每行都加排他锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。

3、意向锁

意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁

意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。

意向锁是InnoDB自动加的,不需要用户干预。

三、 总结                                                                                                                                          

对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁;

对于一般的Select语句,InnoDB不会加任何锁。

事务可以通过以下语句给显示加共享锁或排他锁:

共享锁:SELECT ... LOCK IN SHARE MODE;

排他锁:SELECT ... FOR UPDATE;


原文地址:http://www.cnblogs.com/exceptioneye/p/5373474.html

Mysql常用的锁机制的更多相关文章

  1. MySQL常用的锁机制 ----------顾名思义

    悲观锁与乐观锁: 悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传统的关系型数据库里边就用到了很多这 ...

  2. 巧用MySQL InnoDB引擎锁机制解决死锁问题(转)

    该文会通过一个实际例子中的死锁问题的解决过程,进一步解释innodb的行锁机制 最近,在项目开发过程中,碰到了数据库死锁问题,在解决问题的过程中,笔者对MySQL InnoDB引擎锁机制的理解逐步加深 ...

  3. MySQL的innoDB锁机制以及死锁处理

    MySQL的nnoDB锁机制 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,innodb正常的select ...

  4. MySQL数据库的锁机制

    在并发访问情况下,很有可能出现不可重复读等等读现象.为了更好的应对高并发,封锁.时间戳.乐观并发控制(乐观锁).悲观并发控制(悲观锁)都是并发控制采用的主要技术方式. 锁分类 ①.按操作划分:DML锁 ...

  5. mysql数据库中锁机制的详细介绍

    悲观锁与乐观锁: 悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传统的关系型数据库里边就用到了很多这 ...

  6. MySQL高级以及锁机制

    MySQL高级 推荐阅读: 锁:https://www.cnblogs.com/zwtblog/tag/锁/ 数据库:https://www.cnblogs.com/zwtblog/tag/数据库/ ...

  7. MySQL- InnoDB锁机制

    InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识 ...

  8. MySQL 事务与锁机制

    下表展示了本人安装的MariaDB(10.1.19,MySQL的分支)所支持的所有存储引擎概况,其中支持事务的有InnoDB.SEQUENCE,另外InnoDB还支持XA事务,MyISAM不支持事务. ...

  9. Mysql中的锁机制

    原文:http://blog.csdn.net/soonfly/article/details/70238902 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的 计算资源(如 ...

随机推荐

  1. teleport助手不可以使用剪切板的问题解决

    在使用teleport堡垒机的时候,你使用teleport助手会发现不可以使用剪切板,接下来就是解决方法. 解决办法:更新freerdp 基于环境:win10(win7下更新好像没有用),telepo ...

  2. java几个经典的算法题目----------二维矩阵算法

    public class testClockwiseOutput { public static void main(String[] args) { //1.构建矩阵数据 int[][] arr = ...

  3. 向已有的table中插入数据

    table: <table id="seleted-table" class="table table-bordered table-hover" sty ...

  4. js if和switch,==和===

    今天改插件BoxScroll的时候,因为if里面的条件判断多于两个,于是立马想着改写switch.改到一半,忽然记起来JSHint等代码质量检测工具中的一个要求,用===替换==,不用不可靠的强制转型 ...

  5. gradle本地、远程仓库配置--转

    https://blog.csdn.net/x_iya/article/details/75040806 本地仓库配置配置环境变量GRADLE_USER_HOME,并指向你的一个本地目录,用来保存Gr ...

  6. 网络IO之阻塞、非阻塞、同步、异步总结【转】

    1.前言 在网络编程中,阻塞.非阻塞.同步.异步经常被提到.unix网络编程第一卷第六章专门讨论五种不同的IO模型,Stevens讲的非常详细,我记得去年看第一遍时候,似懂非懂,没有深入理解.网上有详 ...

  7. Golang之并发资源竞争(互斥锁)

    并发本身并不复杂,但是因为有了资源竞争的问题,就使得我们开发出好的并发程序变得复杂起来,因为会引起很多莫名其妙的问题. package main import ( "fmt" &q ...

  8. Java学习--JavaWeb简介

  9. 二:SpringCloud-Eureka

    五:Eureka服务注册与发现 1. 是什么 Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现==服务注册和发现==(请对比Zookeeper). Eureka ...

  10. GIT 基础-基础命令

    环境 centos7 1.安装 #yum install git 2.创建本地仓库 ( 这里用 /www/git) 这里里有个隐藏的文件夹 ```.git``` 为git仓库的配置文件夹, 不可随意修 ...