关于MySQL中的事务
事务的四个特性
原子性:事务要么都发生要么都不发生
一致性:事务在运行前和运行后数据应保持一致
隔离性:类似于线程,事务在运行期间对其他事务不可见
持久性:事务对数据库的操作是永久的,不可逆转
并发事务以及隔离手段
并发事务
在对数据库进行操作时可能会发生并发问题。
在读读操作时一般不涉及并发问题
在读写操作时一般会发生三个问题,脏读,幻读,不可重复读
其中脏读是指事务A进行了修改但没提交,事务B读到了修改,但同时事务A回滚了,所以事务A修改的数据就没了。但是事务B中读到了事务A回滚前的没用的数据,就是读到了脏数据。
幻读和不可重复读差不多,只不过幻读是事务B在读取数据时事务A同时新增了一条数据,同时事务B插入数据时发现该数据已存在。而不可重复读是事务B在读取数据时事务A修改了数据,事务B两次读到的结果不一致。所以幻读是新增,不可重复读是修改。
在写写操作时会发生数据丢失问题
隔离级别
RU(Read Uncommitted) 读未提交,不提供任何锁保护读取的数据,隔离级别最低,脏读、幻读、不可重复读都会发生。
RC(Read Committed) 读已提交,事务修改数据时,事务还没提交的话别的事务无法读取数据,可以隔离脏读。
RR(Repeatable reads) 可重复读,sql第一次读到数据时加悲观锁,让其他事务不可修改,解决了脏读和不可重复读问题。
Serializable 串行化,最高的隔离级别,通过强制事务排序,使得并发操作变串行化,避免了脏读、幻读、不可重复读。
undo log和redo log的区别
redo log:记录事务提交时数据页的物理变化,当服务器宕机时可以用redo log的数据进行回复,实现事务的持久性。
undo log:记录数据被修改的信息。当事务进行insert时,undo log会写入一条delete数据,同理在delete时会写入一条insert数据,当update时会写入一条update相反的数据。这样做时为了在事务进行回滚时,可以将数据恢复到修改前的状态。实现了事务的一致性和原子性。
mvcc
多版本并发控制,维护数据的多个版本,使读写操作没有冲突。
mvcc的实现主要依赖数据库中的隐式字段,undo log日志和readView.
隐式字段: 1.DB_TRX_ID 记录每一次操作的事务id,自增
2.DB_ROLL_PTR 指向undo日志记录的指针,记录了上一个版本的信息。通过该指针可以访问上一个版本的数据。
undo log: 1.回滚日志,存储老版本数据。
2.版本链,记录所有版本的指针,通过版本链可以访问历史版本的数据。
readView: 根据readView匹配规则和事务id判断当前事务是否可以读取某个版本的数据。
不同隔离级别快照读不一样 RC中每一次执行快照读都生成readView,RR中快照读时只第一次生成readView.
当前读和快照读
当前读:每次读取都是当前最新数据,在读时不允许写,在写时不允许读。一般用于修改数据,读取时会加入排他锁来保证读写不共用。
快照读:读取的是快照数据,当前数据在被修改时可以进行读取,读写不冲突。


