mysql 快照读、当前读、幻读、共享锁、排它锁、记录锁(也叫行锁)、间隙锁
事务的四个特点ACID
原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
事务前后数据的完整性必须保持一致。
隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
幻读
幻读是事务不是独立执行的时候发生的一种现象。例如:第一个事务对表中的所有行的某个字段del置为1,同时第二个事务插入了一行del=0的数据,这时候第一个事务的用户就会发现还有没被自己修改的数据,好像发生了幻觉。
脏读
A事务读取了B事务未提交的数据。当事务B发生回滚的时候,A事务读取到的数据就是脏数据。
不可重复读
如果你在时间点T1读取了一些记录,在T2时再想重新读取一次同样的这些记录时,这些记录可能已经被改变、或者消失不见。
由ANSI/ISO定义的SQL-92标准定义的四种隔离级别
为什么不默认:
Serializable级别 只允许一个事务在执行,其它事务必须等待这个事务执行完后才能执行。没有并发,只是单纯的串行。效率堪忧
快照读
正常的select查询(不包括SELECT … LOCK IN SHARE MODE;和SELECT … FOR UPDATE;)
当前读
当前读, 读取的是最新版本, 并且对读取的记录加锁, 阻塞其他事务同时改动相同记录,避免出现安全问题。
mysql隔离技术
在mysql中,提供了两种事务隔离技术, mvcc和next-key 。
mvcc的优势是不加锁,并发性高,缺点是不是实时数据。
next-key的优势是获取实时数据,但是需要加锁。
MVCC(multi version concurrent control) 多版本并发控制
select:事务每次只能读到创建版本号小于等于此次系统版本号的记录,同时行的删除版本号不存在或者大于 当前事务的版本号。
update:插入一条新记录,并把当前系统版本号作为行记录的版本号,同时保存当前系统版本号到原有的行作为删除版本号。
delete:把当前系统版本号作为行记录的删除版本号
insert:把当前系统版本号作为行记录的版本号
next-key锁
Record lock和Gap lock的结合,即除了锁住记录本身,还要再锁住索引之间的间隙。
Record lock(行锁)
单条索引记录上加锁,record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引。所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁(X:排他锁 S:共享锁)。
Gap lock(间隙锁)
锁的区间:根据检索条件向下寻找最靠近检索条件的记录值A作为左区间,向上寻找最靠近检索条件的记录值B作为右区间,即锁定的间隙为(A,B)。
例如 :
select * from t where num =3;那么间隙锁锁定的间隙为:(2,4),当你插入此区间的数据,或者将此区间的值改出去或者区间外改进来时候会被阻塞,保证num=3的行数是固定的。
共享锁
select…from lock in share mode
在扫描到的任何索引记录上加共享的(shared)next-key lock,还有主键聚集索引加排它锁
排它锁
####select…from for update
在扫描到的任何索引记录上加排它的next-key lock,还有主键聚集索引加排它锁
SELECT … LOCK IN SHARE MODE走的是IS锁(意向共享锁),即在符合条件的rows上都加了共享锁,这样的话,其他session可以读取这些记录,也可以继续添加IS锁,但是无法修改这些记录直到你这个加锁的session执行完成(否则直接锁等待超时)。
SELECT … FOR UPDATE 走的是IX锁(意向排它锁),即在符合条件的rows上都加了排它锁,其他session也就无法在这些记录上添加任何的S锁或X锁。
lock in share mode适用于两张表存在业务关系时的一致性要求,for update适用于操作同一张表时的一致性要求
参考文档
/taylor_tao/article/details/7063639
/wwcom123/p/10727194.html