mvcc存在的意义,事务中mvcc如何协调读和写的
事务是一组原子性的SQL查询,事务里的语句,要么全部执行成功,要么全部执行失败
ACID原则:
原子性(Atomicity):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。就像小明余额减去200与支出增加200,相加与之前是一样的。
隔离性(Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
持久性(Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
脏读 : 一个事务读取到另外一个事务未提交的数据
解决:就是把释放锁的位置调整到事务提交之后,此时在事务提交前,其他进程是无法对该行数据进行读取的,包括任何操作
不可重复读:一个事务读取到另外一个事务已经提交的数据,也就是说一个事务可以看到其他事务所做的修改
在一个事务内,多次读同一个数据。在这个事务还没有结束时,另一个事务也访问该同一数据。那么,在第一个事务的两次读数据之间。由于第二个事务的修改,那么第一个事务读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为不可重复读,即原始读取不可重复。
虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
和不可重复读类似,但虚读(幻读)会读到其他事务的插入的数据,导致前后读取不一致
如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行 新数据”。那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样.一般解决幻读的方法是增加范围锁 RangeS,锁定检索范围为只读,这样就避免了幻读。
事务隔离级别有4种:
Read uncommitted(读未提交): 会出现脏读,不可重复读,幻读
Read committed(读已提交):会出现不可重复读,幻读
Repeatable read(可重复读):会出现幻读(但在Mysql实现的Repeatable read配合间隙锁不会出现幻读!)
Serializable(串行):避免以上的情况!
设置事务隔离级别: set [glogal | session] transaction isolation level (Read uncommitted);
死锁:两个或多个以上的事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环。
解决:将持有最少行级排他锁的事务进行回滚。
事务日志:可以提高事务的效率。在修改表时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中。事务日志被持久以后,内存中被修改的数据在后台可以慢慢的刷回磁盘。
MVCC
定义:MVCC(Multi-Version Concurrency Control)即多版本并发控制。
优点:MVCC在大多数情况下代替了行锁,实现了对读的非阻塞,读不加锁,读写不冲突。
缺点:每行记录都需要额外的存储空间,需要做更多的行维护和检查工作。
InnoDB实现MVCC的方式是:
- 事务以排他锁的形式修改原始数据
- 把修改前的数据存放于undo log,通过回滚指针与主数据关联
- 修改成功(commit)啥都不做,失败则恢复undo log中的数据(rollback)