2018-11-19 mysql事务

事务的四大特征(ACID)

A:原子性 : 最小的单位,不可再分隔

C:一致性 :保证事务中的语句,同时成功或者同时失败

I:隔离性 :事务A和事务B具有隔离性

D:持久性 :保存数据

I 隔离性

read uncommitted : 读未提交

可能会出现脏数据:(事务B读到了脏数据)

事务A 事务B
开启事务
insert 数据
开启事务
select数据
commit
rollback

read committed:读已提交

不可重复读:(事务A两次select不一样)

事务A 事务B
开启事务
select数据
开启事务
update数据
commit
select数据
commit

repeatable read :可重复读

幻读:(事务A第二次读的数据和数据库里的不一样)

事务A 事务B
开启事务
select数据
开启事务
update数据
commit
select数据
commit

serializable :串行化

排队:事务的最高级别,在每个读的数据行上,加上锁,使之不可能相互冲突,因此,会导致大量的超时现象

select for update

其他事务必须等待本事务提交了以后才能执行
https://blog.csdn.net/u012888052/article/details/54895704
由于InnoDB预设是Row-Level Lock,底层实现是锁索引的,如果只有主键索引就锁主键索引,只有非主键索引就锁非主键索引,两者都有就按照顺序锁,(主键不明确,table lock) like和 <>

select for update死锁

sessionA锁id=2,然后sessionB锁id = 1其他的等待sessionA释放id=2的锁,然后sessionA在不释放id=2的锁的情况下去操作sessionB锁住的数据,造成两个session互相等待,形成死锁

sessionA sessionB
select * from user where id = 2 for update
select * from user where id < 5 for update
update user set name='aaa' where id = 1

锁级别分类 - 共享锁 & 排他锁 & 意向锁

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

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

用法

SELECT ... LOCK IN SHARE MODE;

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

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

用法

SELECT ... FOR UPDATE;

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

3 意向锁(Intention Lock)
意向锁是表级锁,其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。InnoDB 中的两个表锁:

意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁;
意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。
意向锁是 InnoDB 自动加的,不需要用户干预。

对于INSERT、UPDATE和DELETE,InnoDB 会自动给涉及的数据加排他锁对于一般的SELECT语句,InnoDB 不会加任何锁,事务可以通过以下语句显式加共享锁或排他锁。

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

排他锁:SELECT ... FOR UPDATE;

乐观锁:认为不会发生并发问题

在更新的是判断其他线程在此之前有没有对数据进行修改,一般会使用版本号和CAS实现,乐观锁适合读取频繁的场景

悲观锁:认为一定会发生并发问题,加锁

其他线程想访问数据时,都阻塞可以依靠数据库实现,悲观锁适合写入频繁的场景

你可能感兴趣的:(2018-11-19 mysql事务)