首页 > 数据库技术 > 详细

MySQL-锁机制和事务

时间:2019-10-09 19:21:56      阅读:85      评论:0      收藏:0      [点我收藏+]

一、简介

1)InnoDB存储引擎支持行级锁,其大类可以细分为共享锁和排它锁两类

  • 共享锁(S):允许拥有共享锁的事务读取该行数据。当一个事务拥有一行的共享锁时,另外的事务可以在同一行数据也获得共享锁,但另外的事务无法获得同一行数据上的排他锁
  • 排它锁(X):允许拥有排它锁的事务修改或删除该行数据。当一个事务拥有一行的排他锁时,另外的事务在此行数据上无法获得共享锁和排它锁,只能等待第一个事务的锁释放

2)除了共享锁和排他锁之外,InnoDB也支持意图锁。该锁类型是属于表级锁,表明事务在后期会对该表的行施加共享锁或者排它锁。所以对意图锁也有两种类型:

  • 共享意图锁(IS):事务将会对表的行施加共享锁
  • 排他意图锁(IX):事务将会对表的行施加排它锁

3)举例来说select … lock in share mode语句就是施加了共享意图锁,而select … for update语句就是施加了排他意图锁

4)这四种锁之间的相互共存和排斥关系如下:

技术分享图片

5)所以决定一个事务请求为数据加锁时能否立即施加上锁,取决于该数据上已经存在的锁是否和请求的锁可以共存还是排斥关系,当相互之间是可以共存时则立即施加锁,当相互之间是排斥关系时则需要等待已经存在的锁被释放才能施加

二、InnoDB锁相关系统表

2.1、Information_schema.innodb_trx表

Information_schema.innodb_trx记录了InnoDB中每一个正在执行的事务,包括该事务获得的锁信息,事务开始时间,事务是否在等待锁等信息

Column name Description
TRX_ID InnODB内部标示每个事务的ID
TRX_WEIGHT 表示该事务的权重,近似等于事务锁的行记录数。当发生死锁时,InnoDB会根据此值选择最小的值作为牺牲品.
TRX_STATE 事务当前状态,包括RUNNING, LOCK WAIT, ROLLING BACK, and COMMITTING.
TRX_STARTED 事务开始时间
TRX_REQUESTED_LOCK_ID当事务状态为lock_wait时,表示需要等待的事务的锁ID,对应innodb_locks表里的lock_id;如果是其他值则为NULL
TRX_WAIT_STARTED 当事务状态为LOCK WAIT则代表事务等待锁的开始时间;如果是其他值则为NULL.
TRX_MYSQL_THREAD_ID MySQL线程ID,对应show processlist里的值
TRX_QUERY 事务当前执行的语句
TRX_OPERATION_STATE 事务当前执行的语句类型,不执行则为NULL
TRX_TABLES_IN_USE 执行当前语句需要涉及到几个InnoDB表
TRX_TABLES_LOCKED 当前语句执行施加的行锁对应了几个表
TRX_LOCK_STRUCTS 当前事务保留的锁个数
TRX_LOCK_MEMORY_BYTES 当前事务的锁信息所占用的内存byte数
TRX_ROWS_LOCKED 近似等于当前事务施加的行锁数量,也会包含删除语句所涉及的行锁
TRX_ROWS_MODIFIED 当前事务插入或者修改的行数
TRX_CONCURRENCY_TICKETS
TRX_ISOLATION_LEVEL当前事务的隔离级别
TRX_UNIQUE_CHECKS 唯一键约束检查是开启状态还是关闭状态,常用于批量导入数据时关闭检查
TRX_FOREIGN_KEY_CHECKS外键约束检查是开启还是关闭状态,常用于批量导入数据时关闭检查
TRX_LAST_FOREIGN_KEY_ERROR 上一次外键约束错误的详细信息
TRX_ADAPTIVE_HASH_LATCHED
TRX_ADAPTIVE_HASH_TIMEOUT
TRX_IS_READ_ONLY当值为1时表明事务为只读事务
TRX_AUTOCOMMIT_NON_LOCKING当值为1代表事务中只有一个普通select语句,不会施加任何锁,且由于autocommit是开启的,所以事务只会包含该select语句

2.2、Information_schema.innodb_locks表

Information_schema.innodb_locks记录了InnoDB中事务在申请但目前还没有获取到的每个锁信息,以及当前事务的锁正在阻止其他事务获得锁

Column nameDescription
LOCK_IDInnoDB内部标示每个锁的ID
LOCK_TRX_ID表示持有该锁的事务ID,对应innodb_trx表中的事务ID
LOCK_MODE表示该锁的模式。可以是S[,GAP], X[,GAP], IS[,GAP], IX[,GAP], AUTO_INC, UNKNOWN. 除了AUTO_INC andUNKNOWN的锁模式,其他的锁模式都暗含是GAP间隔锁
LOCK_TYPE表示锁类型,可以是RECORD表示行锁, TABLE表示表锁
LOCK_TABLE该锁涉及的表名
LOCK_INDEX当为行锁时,则代表该锁涉及的索引名,否则为NULL.
LOCK_SPACE当为行锁时,则表示被锁记录所在的表空间ID;否则为NULL
LOCK_PAGE当为行锁时,则表示被锁记录所在的数据页数量;否则为NULL
LOCK_REC事务锁定行的数量,若是表锁则该值为NULL
LOCK_DATA事务锁定记录主键值,若是表锁则该值为NULL

2.3、Information_schema.innodb_lock_waits表

Information_schema.innodb_lock_waits记录了InnoDB中事务之间相互等待锁的信息

Column name Description
REQUESTING_TRX_ID 请求锁被阻止的事务ID
REQUESTED_LOCK_ID 请求锁被阻止的锁ID
BLOCKING_TRX_ID 阻止上述事务获得锁的事务ID
BLOCKING_LOCK_ID 阻止事务对应的的锁ID

三、行级锁

1)行级锁是施加在索引行数据上的锁,比如SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE语句是在t.c1=10的索引行上增加锁,来阻止其他事务对对应索引行的insert/update/delete操作。

2)当一个InnoDB表没有任何索引时,则行级锁会施加在隐含创建的聚簇索引上,所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的

创建表:create table temp(id int,name varchar(10));

插入数据:insert into temp values(1,‘a‘),(2,‘b‘),(3,‘c‘);

步骤 链接1 链接2
1

##update加排他锁
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> update temp set name=‘aa‘ where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

2

##update等待第一个锁释放
mysql> update temp set name=‘bb‘ where id=2;

3

##commit释放锁
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

4 ##等待结束,释放锁 Query OK, 1 row affected (6.84 sec) Rows matched: 1 Changed: 1 Warnings: 0
5

##释放自己的锁
Commit;










































MySQL-锁机制和事务

原文:https://www.cnblogs.com/hujinzhong/p/11643442.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!