对事务本身的理解
1.事务是一组原子性的SQL查询,对于事务内的查询要么完全成功,要么完全失败。
2.mysql默认的事务是自动提交的,即autocommit=true,也就是说一个SQL查询即是一个事务。
3.对于多条语句,通过start transaction;和commit(rollback)进行配合,将多条语句包装为一个更大的事务单元。
4.如果设置autocommit=false,那么语句将不会被提交,直到使用rollback,或者commit。
5.事务的特性ACID(原子性,一致性,隔离性,持久性)
原子性:要求一个事务不可分割,里面的语句要么全部成功,要么全部失败,不会看到中间状态。
一致性:个人感觉是数据库数据本身和数据之间的约束关系在事务前后是不会变的。
隔离性:即一个事务在提交之前,他对记录的修改对其他事务不可见。为了防止过多的锁,MYSQL通过MVCC实现。
持久性:即事务对记录的修改,在提交时候会被永久的保存到磁盘上。MYSQL为了提高事务效率,存储引擎在修改数据时通常只修改内存数据,同时将修改操作记录到“事务日志”中,再异步的刷回磁盘。
对事务隔离级别的理解
Read Uncommited
未提交读,数据库级别的最低层次,事务会读到其他事务未提交的数据。这种事务级别只保证磁盘不出问题。产生的问题即脏读。
如图:
左侧事务中对age=4的记录进行了更新但是未提交,右侧事务使用uncommited read 读到了未提交的记录,使用其他事务级别则读到原值。
Read Committed
与read uncommitted不同,这个级别下的事务读不到其他事务未提交的记录.。这个在上一张图中就有体现。虽然Read Committed能够保证事务读到别人提交的记录,但是仍然存在在同一个事务中,对同一条记录读两次,值发生变化的情况。即两次select中有其他事务对该记录有更新。这种不一致的情况,成为“不可重复读”
如图:
在read committed下右边session启动一个事务,第一次查询age=4的记录值为xiaotong,然后左边对age=4的记录更新为myname,右边事务再查询时,发现记录已经变名字了。这就是在一个事务中对一条记录反复读取出现不一致情况,称之为“不可重复读”
Repeatable Read(mysql默认级别)
可重复读。针对read committed出现的情况,repeatable read 就是一种在事务内对统一记录反复查询不会出现不一致的事务级别,
如图:
如果设置右边事务级别为repeatable read,那么无论在事务过程中,其他事务如何更改记录值,右边事务对统一记录的查询结果始终一致。
Serializable(序列)
隔离级别最高的一种事务级别,要求不同事务之间串行执行,这样能够保证事务之间没有任何干扰,但是这样查询的效率很低,吞吐量低,需谨慎使用。序列的级别下,是不会存在幻读的,即在一个事务中,对一批事务进行更新,而在令一个事务中插入了一条新记录满足条件。这样更新事务就会发现更新操作在提交之后仍有满足条件而未更新的,称之为“幻读”。
事务相关常用sql
查询当前session的事务隔离级别
select @@tx_isolation
查看全局事务隔离级别
select @@global.tx_isolation
这是session的事务级别
set session(global) transaction isolation level read uncommitted
(read committed,repeatable read,serializable)