mysql事务和锁

一、事务
事务是一组原子性的SQL查询语句,也可以被看做一个工作单元。
1、特性(ACID)
automicity:原子性,事务所引起的数据库操作,要么都成功,要么都失败
consisitency:一致性,事务执行前的总和和事务执行后的总和是不变的
isolation:隔离性, 某个事务的结果只有在完成之后才对其他事务可见
durability:持久性,一旦事务成功完成,系统必须保证任何故障都不会引起事务表现出不一致性
2、隔离级别
read uncommitted: 可能读取到其他事务中未提交修改的数据(脏读)
read committed: 只能读取到已经提交的数据(不能重复读)
repeatable read: 在同一个事务内的查询都是事务开始时刻一致的,innodb的默认级别。(可重复读,幻读)
serializable: 完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
RU 可能 可能 可能
RC 不可能 可能 可能
RR 不可能 不可能 可能
Serializable 不可能 不可能 不可能

 

3、持续读
基于MVCC,提供给查询一个数据库在一个时间点的快照;只读取同一个在事务中第一次读所确定的快照
4、锁定读
二、锁
1、Innodb是行级锁:
S:共享锁
X:排他锁
IS:意向共享锁
IX:意向排他锁

(1)Record lock:记录锁
(2)Gap lock:间隙锁
(3)Next-key lock:记录锁和间隙锁的结合
(4)Insertion intention gap lock:看名字就知道了

2、锁兼容
(1)INSERT操作之间不会有冲突。
(2)GAP,Next-Key会阻止Insert。
(3)GAP和Record,Next-Key不会冲突
(4)Record和Record、Next-Key之间相互冲突。
(5)已有的Insert锁不阻止任何准备加的锁。

3、sql对应的锁
(1)select...from:读数据库的快照,不加锁,除非数据库的隔离界别为serializable。
(2)select...from...in share mode:在扫描到的所有索引上加next-key S锁
(3)select...from...for update:在扫描到的所有索引上加next-key X锁
(4)update...where...:在扫描到的每个索引上加next-key X锁
(5)delete from...where...:在扫描到的每个索引上加next-key X锁
(6)insert:在被插入的行上加X锁。这个锁是索引记录锁,不是next-key锁(所以没有gap锁),同时不阻止别的事务往这个记录的gap区间插入新的记录。
在插入这行之前,会首先在这行加一个Insertion intention gap锁。这个锁表示多个事务插入只要不是在同一个gap中的同一个点,那么向这个gap插入记录时不需要等待。
先加Insertion intention gap lock(IX),再加Record lock(X)

4、隔离级别对Next-Key锁的影响
A. Read Uncommitted和Read Committed时,不需要在间隙上加锁,Nexk-Key变成Record锁。
B. Repeatable Reads 和 Serializable时,通常情况下使用Next-key锁。

5、死锁
(1)死锁事务的回滚机制:
a、如果一个事务修改了non-transactional表(如MyISAM表,修改不能回滚),另一个表没有。
则没有修改non-transactional的会被回滚。
b、如果2个事务都修改了non-transactional表或者都没有。则比较2个事务修改的记录数和加
的锁数量。总和小的事务会被回滚。

6、实验

现有表t7,结构如下:

CREATE TABLE `t7` (
  `i` int(11) NOT NULL DEFAULT 0,
  PRIMARY KEY (`i`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

表中数据:

+----+
| i  |
+----+
|  1 |
|  3 |
|  7 |
| 10 |
+----+ 

使用默认的RR隔离级别

事务1 事务2
begin;  
  begin;
delete from t7 where i=5;(在区间(3,7)加X锁)  
  insert into t7 values (4);(wait,4已经在t1的锁区间内了,所以不能获得锁,阻塞)
  insert into t7 values (6);(wait,6已经在t1的锁区间内了,所以不能获得锁,阻塞)
  insert into t7 values (7);( Duplicate entry ‘7‘ for key ‘PRIMARY‘,并且会在7上加S锁)
  insert into t7 values (3);( Duplicate entry ‘3‘ for key ‘PRIMARY‘,并且会在3上加S锁)
  insert into t7 values (2);(ok,不在锁区间,不会阻塞)
rollback; rollback;
   
begin  
  begin
delete from t7 where i=3;(在3上加X锁)  
  insert into t7 values (2);(ok)
  insert into t7 values (6);(ok)
  insert into t7 values (3);(wait,3上的锁已经被t1获得,阻塞)
rollback; rollback;
   
begin;  
  begin;
insert into t7 values(5);(在5上加record锁)  
  insert into t7 values(6);(ok)
  insert into t7 values(5);(wait,3上的锁已经被t1获得,阻塞)
rollback; rollback; 

mysql事务和锁,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。