mysql事务的特性:ACID
即
原子性atomicty,
要么都完成要么都失败
一致性Consistency,
如果事务是并发的也必须如同串行事务一样执行
隔离性Isolation,
如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统
持久性Durability
在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚
关于隔离性
一.隔离级别
1.读未提交(read uncommitted)
指事务未提交时,他做的变更能被其他事务给观察到
查看事务隔离级别
SELECT @@tx_isolation;
show variables like 'transaction_isolation';
修改事务等级(session只影响当前shell,修改global后需要重启会话)
set session/global transaction isolation level read uncommitted;
此时再开启一个shell,两边同时开启事务
按照这个顺序来执行
我们观察到V1,V2,V3的值都为2
即事务未提交时,他做的变更能被其他事务给观察到
注意:begin/start transaction命令并不是真正开启事务,而是命令之后的第一条语句才开启事务。start transaction with consistent snapshot则为立即开启
2.读提交(read committed)
同理重复上步骤
所以V1=2,V2=V3=3
即事务在提交后所做的变更才能被观察到
3.可重复读(repeatable read)
一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的
所以V1=V2=3 ,V3=4
4.串行化(serializable)
顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行
事务原理
可重复读和读已提交两者为保持事务的一致性(如果事务是并发的也必须如同串行事务一样执行),都会产生视图,不同的是可重复读是在开启时创建,而读已提交是每一行语句都会创建。
注意:
虽然可重复读在开启事务创建视图, 但是如果在事务中进行了更新操作(相同行),再查询数据 此时也能看到其他事务提交后的变更(相当于又重新创建了视图)
我们试想一下,如果不可能B的结果那么在A提交后,age=2,B的操作就会被丢失! 此时我们就明白了:更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”(current read)。即读取最新数据
####尽量减少长事务的使用
以可重复读为例,每条记录在更新时会同时记录一条回滚日志,记录上的最新值通过回滚操作,都可以得到前一个的状态的值(这也是回滚操作的原理)。回滚日志在没有事务用到这些的时候会被删除,因为回滚日志的存在,若为长事务则会记录很老的内容导致占用大量的存储空间。
>mysql5.5之前,回滚日志是跟数据字典一起放在ibdata中的,即使长事务最终被提交,回滚段被清理,文件也不会变小!!!也就是说甚至可能出现数据20G,回滚段200G的情况