1.事务的基本特性
2.并发问题
脏读:破坏隔离性,看到了另一个事务未提交的数据
不可重复读(强调的是数据的更新)
幻读(强调的是数据的增减)
InnoDB引擎中的四种隔离级别
设置隔离级别
set tx_isolation= 'read-uncommitted' 'read-committed' 'repeatable-read' 'serializable'
-
read uncommit(读未提交):有脏读、不可重复读、幻读问题
-
read commit (读已提交):有不可重复读、幻读问题(oracle默认隔离级别)
写操作会加写锁,只有事务提交之后,其他事务才能读写
当前读就是悲观锁的具体功能实现 -
repeatable read(可重复读):有幻读(mysql默认隔离级别)
快照读可以读写同时,不能写写同时
-
serializable (串行):上面问题全部解决 ,给所有读操作加写锁实现
mysql 锁
读锁(共享锁、S锁):select … lock in share mode;
读锁是共享的,会阻塞写,不会阻塞读
写锁(排它锁、X锁):select … for update;
写锁是排他的,update、delete、insert都会加写锁,会阻塞其他的写和读,
MyISAM在select前,会自动给涉及到的表加读锁,写操作会给表自动加写锁
InnoDB在select前,不会加锁,但写操作会加行锁
MVCC多版本并发控制
实现原理主要依赖隐藏字段,undo log ,read view来实现
1.隐藏字段
DB_TRX_ID:创建或修改该记录的事务id
DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本
2.undo log:记录数据的历史版本
3.read view:可见性判断
trx_list:活跃的事务id
up_limit_id:list中的最小id
low_limit_id: 下一个要分配的id
读已提交,语句级快照,每个快照读都会生成并获取最新的ReadVIew
可重复读,事务级快照,同一个事务中的第一个快照才会创建ReadView,之后的快照读都是同一个ReadView
redo log
redo log的主要作用就是用来记录已成功提交事务的修改信息,可以防止因宕机导致修改的数据未能及时持久化到磁盘中,系统重启之后就可以读取redo log来恢复最新的数据。从而实现事务的持久性。
undo log
每条数据变更(insert/update/delete)操作都伴随着一条undo log的生成,并且回滚日志必须先于数据持久化到磁盘上;
所谓的回滚就是根据undo log日志做逆向操作,比如delete的逆向操作为insert,insert的逆向操作为delete,update的逆向操作为update等;