Mysql对于事务并发处理带来的问题,脏读、不可重复读、幻读的理解

本文主要是介绍Mysql对于事务并发处理带来的问题,脏读、不可重复读、幻读的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、缘由

  众所周知MySQL从5.5.8开始,Innodb就是默认的存储引擎,Innodb最大的特点是:支持事务、支持行级锁。既然支持事务,那么就会有处理并发事务带来的问题:更新丢失、脏读、不可重复读、幻读;相应的为了解决这四个问题,就产生了事务隔离级别:未提交读(Read uncommitted),已提交读(Read committed),可重复读(Repeatable read),可序列化(Serializable)。

  之前在看事务隔离级别的时候,基本是一知半解。再次碰到,还是浆糊,所以这里打算彻底搞明白、清楚,也好后续的学习。

 

二、解决办法:

1、概念说明:   

  更新丢失:最后的更新覆盖了其他事务之前的更新,而事务之间并不知道,发生更新丢失。更新丢失,可以完全避免,应用对访问的数据加锁即可。

  脏读:(针对未提交的数据)一个事务在更新一条记录,未提交前,第二个事务读到了第一个事务更新后的记录,那么第二个事务就读到了脏数据,会产生对第一个未提交数据的依赖。一旦第一个事务回滚,那么第二个事务读到的数据,将是错误的脏数据。

  不可重复读:(读取数据本身的对比)一个事务在读取某些数据后的一段时间后,再次读取这个数据,发现其读取出来的数据内容已经发生了改变,就是不可重复读。

  幻读:(读取结果集条数的对比)一个事务按相同的查询条件查询之前检索过的数据,确发现检索出来的结果集条数变多或者减少(由其他事务插入、删除的),类似产生幻觉。

 

2、不可重复读和幻读的区别:

不可重复读

重点是修改:同样的条件下,你读取过的数据,再次读取发现值不一样了。

例子:(只是为了说明区别,没有事务隔离级别约束)

事务1:Jack读取自己的工资为1000,事务并没有结束:

select salary from employee empId ="Jack"; 

 

事务2:财务人员修改了Jack的工资为2000,并提交事务(事务1不知道):

update employee set salary = 2000;

commit;

在事务1中,再次读取Jack的工资时,工资变为2000

select salary from employee empId ="Jack";

在一个事务中前后两次读取的结果值并不一致,导致了不可重读读

 

幻读

重点在于新增或者删除(数据条数的变化):同样条件下,第一次和第二次读出来的记录条数不一样。

例子:

目前工资为1000的员工有10人。

事务1:读取所有工资为1000的员工,事务进行中

select count(*) from employee where salary = 1000;

共读取到10条记录。

事务2:同时插入一条新的员工记录,工资也为1000

insert into employee(empId, salary) values('Tom', 1000);

commit;

事务1:再次读取所有工资为1000的员工

select count(*) from employee where salary = 1000;

共读取到了11条记录,这样就像产生了幻读。

 

三、事务隔离级别:

  并发处理带来的问题中,更新丢失可以完全避免,由应用对数据加锁即可。脏读、不可重读度、幻读,其实都是数据库的一致性问题,必须由一定的事务隔离机制来解决。其中一种方法是:不用加锁,通过一定的机制生成一个数据请求时间点的一致性快照,并用这个快照来提供一个界别的一致性读取。从用户的角度看,好像是数据库提偶拱了统一数据的多个版本。这种技术叫做:数据库多版本并发控制,MVCC 多版本数据库。

  事务隔离的本质是使事务在一定程度上串行化执行,显然和并发机制是矛盾的。数据库的事务隔离越严格,并发负作用越小,代价越高(影响并发访问了呗)。

  为了解决隔离和并大的矛盾,IOS SQL92规定了4个隔离级别。(隔离==串行

 

MySQL 默认的级别是:Repeatable read 可重复读。

这篇关于Mysql对于事务并发处理带来的问题,脏读、不可重复读、幻读的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/579448

相关文章

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

Vue3绑定props默认值问题

《Vue3绑定props默认值问题》使用Vue3的defineProps配合TypeScript的interface定义props类型,并通过withDefaults设置默认值,使组件能安全访问传入的... 目录前言步骤步骤1:使用 defineProps 定义 Props步骤2:设置默认值总结前言使用T

Spring 中的切面与事务结合使用完整示例

《Spring中的切面与事务结合使用完整示例》本文给大家介绍Spring中的切面与事务结合使用完整示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录 一、前置知识:Spring AOP 与 事务的关系 事务本质上就是一个“切面”二、核心组件三、完

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

MySQL中On duplicate key update的实现示例

《MySQL中Onduplicatekeyupdate的实现示例》ONDUPLICATEKEYUPDATE是一种MySQL的语法,它在插入新数据时,如果遇到唯一键冲突,则会执行更新操作,而不是抛... 目录1/ ON DUPLICATE KEY UPDATE的简介2/ ON DUPLICATE KEY UP

MySQL分库分表的实践示例

《MySQL分库分表的实践示例》MySQL分库分表适用于数据量大或并发压力高的场景,核心技术包括水平/垂直分片和分库,需应对分布式事务、跨库查询等挑战,通过中间件和解决方案实现,最佳实践为合理策略、备... 目录一、分库分表的触发条件1.1 数据量阈值1.2 并发压力二、分库分表的核心技术模块2.1 水平分