事务及其ACID属性
原子性(Atomicity) :当前事务的操作要么同时成功,要么同时失败。原子性由undo log日志来实现。
一致性(Consistent) :使用事务的最终目的,由其它3个特性以及业务代码正确逻辑来实现。
隔离性(Isolation) :在事务并发执行时,他们内部的操作不能互相干扰。隔离性由MySQL的各种锁以及MVCC机制来实现。
持久性(Durable) :一旦提交了事务,它对数据库的改变就应该是永久性的。持久性由redo log日志来实现。
![](https://i-blog.csdnimg.cn/blog_migrate/ac1427a00020bedbca07aa62af8fe229.png)
读未提交
新建查询窗口A事务和B事务并设置隔离级别为读未提交:set tx_isolation='read-uncommitted';
在窗口A事务下查询一条数据但是不提交事务如下
![](https://i-blog.csdnimg.cn/blog_migrate/b90f0c07140fee30c5f66b8f8647a906.png)
在新建窗口B事务下修改一条数据但是也不提交事务如下
![](https://i-blog.csdnimg.cn/blog_migrate/a99a7270ee977eb40bff88ec8b3a0a9f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0e74b7a7d10f786a69731111ac86b1e3.png)
再通过A事务查询本条数据会发现本条数据是B事务修改但是没有提交事务的数据这就是脏读。
这种情况会导致假如B事务修改完数据还没提交事务,但是A事务读取到B事务未提交的数据去做处理就会导致A事务处理的结果是不对的。
读已提交
新建查询窗口A事务和B事务并设置隔离级别为读已提交:set tx_isolation='read-committed';
A事务修改读已提交并查询数据但是没有提交事务的情况
![](https://i-blog.csdnimg.cn/blog_migrate/e79dc07416b0188cbf9a58fba3a9be1e.png)
B事务修改本条记录并不提交事务
![](https://i-blog.csdnimg.cn/blog_migrate/280abc62de3e7a5df29faf450ebc326e.png)
通过A事务窗口去查询本条记录发现查询不到B事务修改后的数据,这就是读已提交解决了脏读问题,但是B事务提交事务后A事务还没有提交事务可是A事务再次查询的时候会读取到B事务修改后的数据这就会产生新的问题不可重复读。
![](https://i-blog.csdnimg.cn/blog_migrate/41ab02f3a6c1587cbc446aa13abcdbb3.png)
可重复读
新建查询窗口A事务和B事务并设置隔离级别为可重复读:set tx_isolation='repeatable-read';
A事务查询但不提交事务所查询到的数据:
![](https://i-blog.csdnimg.cn/blog_migrate/36886a8f6166f482cdd24cc08302d90d.png)
B事务修改本条数据提交事务并查询数据:
![](https://i-blog.csdnimg.cn/blog_migrate/3d0438e47b2322b22edc1122a8514b42.png)
现在这条数据字段balance的数据应该是500,但是在A事务中这条数据的时候还是450这样就解决了不可重复读问题。但是在B事务下新增一条数据后通过A事务再去查询B事务是查询不到的但是A事务可以修改B事务新增的这条数据所以就会产生幻读的问题,然后再去查询又可以查询到这条数据了。