具体表现:
脏读:对于两个事务,t1,t2,如果T1读取了已经被t2修改过的但是还没有提交的数据,但是最后t2回滚了,t1读取的内容是临时并且无效的
不可重复读:对于两个事务,T1,T2读取了一个字段的值,但是T2更新了这个字段,T1再次读取的时候,两读取的数据是不一致的
幻读:对于两个事务T1,T2,T1从一个表中按照一定的条件读取数据,接着T2将表进行了更新,插入几行新数据,当T1再次以相同的条件进行读取的时候,会出现新的数据
不可重复读更加侧重于对于数据的修改,解决这个问题:将满足条件的行锁起来
幻读更加侧重于新增数据或者删除数据,解决办法:锁表
所以mysql数据库中有自带的隔离级别,默认是可重复度级别
隔离级别:
未提交读(读取未提交的数据):
允许事务读取未被其他事务提交的更改,所以脏读、不可重复读、幻读都会出现
已提交读(读取提交内容):
只允许事务读取已经被其他事务提交的更改,能够解决脏读问题,但是不可重复读和幻读没有解决
可重复读(可重读):
确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务多这个字段进行更新,可以避免脏读和不可重复读,但是幻读还是会出现的
可序列化(可串行化):
确保事务可以从一个表中读取相同的行,在这个事务持续期间,不允许其他事务对于表数据执行插入,更新和删除操作,会解决所有的并发问题,但是性能很低
注意点:
oracle支持俩种2种,已提交读,可序列化,默认的是已提交读
mysql是4种,默认的是可重复读
如何设置隔离级别呢:(如下)
设置隔离级别
# 未提交读
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
#可提交读
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
#可重复读
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
# 可序列化
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
查看隔离级别:
select @@tx_isolation;
如需要改级别,每次打开数据库操作都需要手动修改,不然都是默认状态。除修改全局变量外