事务及mysql中的隔离级别
事务,一个或一组sql语句组成的执行单元,是最小的执行单元,要么全执行,要么全不执行。如果单元中某条sql语句执行失败,整个单元将会回滚,所有受影响的数据返回到事务开始前的状态。
事务具有ACID
四个属性
A atomicity 原子性
,原子性是指一个事务是不可再分割的单位,事务中的操作要么都发生,要么都不发生。
C consistency 一致性
事务必须使数据从一个一致性状态,切换到另外一个一致性状态。比方在一个转账过程中发生的金钱转换,转账前后,钱的总额是不变的,转账前A有x元,B有y元,转账完成之后A有z元,B有w元,则 x + y 是等于 z+ w的。
I isolation 隔离性
指一个事务的执行不能被其他的事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不得相互干扰。
D durability 持久性
一个事务一旦提交之后,对数据库中数据的改变是永久性的,接下来其他操作和数据库故障不应该对其有任何影响。
mysql中,
insert
,update
,delete
语句都是隐式事务,想要手动设置一个事务,则需要将autocommit
设置为 0,等整个事务语句都执行完毕之后,再写commit
提交 或rollback
回滚。
比方可以这么写一个事务:
set autocommit = 0;
[start transaction;]
要执行的sql语句;
[savepoint 回滚点名字]
...#一般就是增删改查语句
...
commit | rollback [ to 回滚点名字]; # 设置回滚点前的语句都会被提交
当不同事务访问相同数据时,会发生一下几个问题,
脏读
,幻读
,不可重复读
脏读
是指一个事务读取了另一个事务已经更改之后的数据,但是过了一会儿该事务又将事务回滚的情况。
不可重复读
是指一个事务读取的一个数据前后不一致的情况。多次重复读取数据的结果不一致。
幻读
一个事务读取数据的过程中有另一个事务执行了插入语句,导致当前事务读取数据前后数量不一致。比方一条更新全表的语句,开始执行前有n行数据,如果执行过程中,有另一事务插入了若干行数据,则执行完毕更新语句之后,受影响的行数前后会不一致。
mysql可以通过设置隔离级别
可以避免以上几种现象
mysql的默认事务隔离级别为repeatable read
,此种级别可以避免脏读和不可重复读的产生。次外还有以下几种
隔离级别/会出现的问题 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
read uncommitted | ✔ | ✔ | ✔ |
read committed | × | ✔ | ✔ |
repeatable read | × | × | ✔ |
serializable | × | × | × |
查看当前的隔离级别:select @@tx_isolatioin;
设置当前连接的隔离级别: set transaction isolation level 隔离级别名字