先了解下几个概念:脏读、不可重复读、幻读。
脏读
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。 不可重复读是指在对于数据库中的某行记录,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,另一个事务修改了数据并提交了。
幻读
幻读是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录。对幻读的正确理解是一个事务内的读取操作的结论不能支撑之后业务的执行。假设事务要新增一条记录,主键为id,在新增之前执行了select,没有发现id为xxx的记录,但插入时出现主键冲突,这就属于幻读,读取不到记录却发现主键冲突是因为记录实际上已经被其他的事务插入了,但当前事务不可见。
不可重复读
不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
事务隔离就是为了解决上面提到的脏读、不可重复读、幻读这几个问题。
MySQL数据库为我们提供的四种隔离级别:
Serializable (串行化):通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。 Repeatable read (可重复读):MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行,解决了不可重复读的问题。 Read committed (读已提交):一个事务只能看见已经提交事务所做的改变。可避免脏读的发生。 Read uncommitted (读未提交):所有事务都可以看到其他未提交事务的执行结果。 查看隔离级别:
select @@transaction_isolation;
设置隔离级别:
set session transaction isolation level read uncommitted;
生产环境数据库一般用的什么隔离级别呢? 生产环境大多使用RC。为什么不是RR呢?
可重复读(Repeatable Read),简称为RR 读已提交(Read Commited),简称为RC
缘由一:在RR隔离级别下,存在间隙锁,导致出现死锁的几率比RC大的多! 、
缘由二:在RR隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行!
也就是说,RC的并发性高于RR。
并且大部分场景下,不可重复读问题是可以接受的。毕竟数据都已经提交了,读出来本身就没有太大问题!
评论