数据库事务脏读、幻读、不可重复读的解决方法

概念

  • 脏读:脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。

  • 幻读
    幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样。

  • 不可重复读
    事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。

  • 丢失的修改
    两个事务同时修改同一行数据并提交,其中一个事务覆盖了另一事务的修改。

解决方法

以上出现的都是数据库事务隔离级别的问题,SQL标准定义了事务隔离级别分为四种(级别递减):

  • Serializable (串行化):最严格的级别,事务串行执行,资源消耗最大;简言之,它是在每个读的数据行上加上共享锁,但可能导致大量的超市现象和锁竞争。

  • REPEATABLE READ(可重复读) :保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但不能避免“幻读”,但是带来了更多的性能损失。

  • READ COMMITTED (提交读):大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”,但不能避免“幻读”和“不可重复读取”。该级别适用于大多数系统。

  • Read Uncommitted(未提交读) :事务中的修改,即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读取”。

隔离级别脏读幻读不可重复读
Read Uncommitted(未提交读)可能可能可能
Read Commited (已提交读)不可能可能可能
Repeatable Read(可重复读)不可能可能不可能
Serializable (串行化)不可能不可能不可能

修改Mysql的事务隔离级别

# 修改配置文件
cd /etc/mysql/mysql.conf.d/
sudo vim mysqld.cnf

# 添加以下代码
transaction-isolation=READ-COMMITTED

在Oracle,SqlServer中都是选择读已提交(Read Commited)作为默认的隔离级别,而Mysql却选择可重复读(Repeatable Read)作为默认隔离级别

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值