社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
平常开发过程中免不了对数据库的操作,并且还会有多个线程同时开启事务后对数据库进行访问,那此时不可避免就会出现多个线程之间交叉访问而导致数据的不一致,通过对数据库的隔离级别进行设置可以保证各线程数据获取的准确性。
在介绍隔离级别之前先要弄清楚数据库在并发事务下会出现的一些状态:
不可重复读是针对于多次读取同一条数据出现不同结果,幻读是多次读取而产生的记录数不一样
为解决上述问题可以给数据库设置响应的隔离界别,有以下5中隔离级别:
在MySQL数据库中查看当前事务的隔离级别:
select @@tx_isolation;
在MySQL数据库中设置事务的隔离级别:
set tx_isolation='read-uncommitted';
set tx_isolation='read-committed';
set tx_isolation='repeatable-read';
set tx_isolation='serializable';
下面进行相应的测试,cmd打开两个窗口登录mysql,模拟事务1(左)和事务2(右)
1、read-uncommitted
将事务1设置隔离级别为read-uncommitted,并且事务1、事务2同时开启事务,查看bank表中初始的数据。
在事务2中更新 jack 的钱为 1000 但不提交事务,然后两边查询结果。从图中可以看到事务1查询的结果显示数据已更改,也就是读取到事务2未提交的数据,这种情况称之为脏读。
2、read-committed
将事务1设置隔离级别为read-committed,并且事务1、事务2同时开启事务,查看bank表中初始的数据。
在事务2中更新 jack 的钱为 200 但不提交事务,然后两边查询结果。通过设置为read-commited,事务1 将不会读取到事务2未提交的数据,避免了脏读。
3、repeatable-read
在上一步中,事务2更新完后提交数据,然后事务1 事务2再次查询。在事务2提交事务后,事务1(事务1没有提交)前后两次的查询结果不一致了,这里就产生了不可重复的状态(参考上面的定义及示意图)
将事务1设置为repeatable-read,并且事务1、事务2同时开启事务,查看bank表中初始的数据。
在事务2中更新 jack 的钱为 500 提交事务,然后两边查询结果,事务1(事务1不提交事务)中的数据并未受事务2更新的影响,避免了不可重复读的情况。
4、serializable
将事务1设置隔离级别为serializable,并且事务1、事务2同时开启事务。
然后在事务1中执行一个查询语句但不提交事务,接着在事务2中执行一条更新语句,会发现事务2中输入SQL语句按下回车键后SQL语句并未执行,处于等待状态。
只有当事务1提交事务后事务2的SQL语句才会执行,这就是事务的串行化,多个事务排队按照先后顺序依次执行。
以上就是对数据库的隔离级别简单的介绍,有问题欢迎指出~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!