热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

数据库事务并发产生的问题以及事务的隔离级别

数据库事务并发产生的问题以及事务的隔离级别-之前我们谈到过,数据库通过调整事务之间的隔离级别来提高事务的性能。那么接下来,我们来首先说说事务之间可能互相遇到的问题。大家都知道事

之前我们谈到过,数据库通过调整事务之间的隔离级别来提高事务的性能。
那么接下来,我们来首先说说事务之间可能互相遇到的问题。

大家都知道事务只有提交后,才会真正的持久化到硬盘,倘若出现出现了回滚的操作,则事务所有操作的影响都会被回退掉。那么假若事务在执行过程中,其他事务读取到了当前的操作结果,但是当前事务后边回滚了,那么其他事务相当于读取到了错误的数据。
举个例子
老板告诉HR,技术员工从下个月开始涨工资。技术小A从小道消息得知后,非常开心,准备把自己的单车换成摩托。后边老板发现公司的债务堆积严重,告知HR取消该加薪计划。得知真相的小A眼泪流下泪,只能含着泪去找摩托店老板退货。
流程如下图:

理论上小A等员工不应该从侧面提前获知公司的加薪计划,而应该在公司正式发文后(事务提交后)才可获知。这个问题就是我们常说的脏读。此时的隔离级别我们称之为读未提交,也就是说还没有正式公布的数据,可以被提前获知到。(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )
如何解决这个问题呢?
公司特别进行了申明,任何未经公司正式发文的消息,全部为不实消息,大家不可以信赖,出现任何问题后果自负,大家只能相信眼见为实的那些消息。这种隔离级别我们称之为读已提交,也就是只能读到公司正式发文的信息,对于那些未通过正式发文的消息,直接无视掉。
问题好像已经解决了。
年会前公司正式发文,由于今年业绩成长明显,经讨论, 全员加薪。
小A看了看自己骑了两年的单车,决定换一辆摩托。正所谓搏一搏单车变摩托。
于是小A兴冲冲的跑到摩托车行,预定了自己中意已久的摩托。
然而接下来小A在参加年会的过程中,老总在会议上特别宣布,由于上一年公司业绩的特别突出,经过公司董事会的宣布,包括小A在内的所有员工,特别增发配股。
小A看了看微信已经给摩托车老板转发的定金,又看了看最新的路虎,陷入的沉思。正所谓赌一赌摩托变路虎,年会结束后,小A火速联系摩托车老板,一哭二闹的总算把押金退了,去隔壁的4S店下单了路虎。
流程如下图:

对于这种每次读取到待遇都不一样,导致处理过程中出现了错误的处理的场景,我们称之为不可重复读。啥意思呢?也就是说即使公司正式发文后(提交后),也可能存在不确定性,因为公司可能反复提交数据,导致你拿到的数据仍然是脏数据,甚至你已经根据历史数据进行了错误的处理。此时的隔离级别我们称之为读已提交。
那么怎么解决这个不可重复读的问题呢?
也就是你操作期间,其他人不能改数据。很简单,你用什么数据锁住什么数据就好了,如果你需要根据薪酬要做出消费的判断,那么只要锁住薪酬就好了。

这样好像问题已经解决了,但是通过一系列操作预订完路虎的你,回家发现,当初私房钱买的比特币,现在已经涨到3万美金了,折合下来资产都过亿了。(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )望着一串你的小屏手机都快显示不下的数字,你再次陷入沉思。从沉思缓过来后,你拨通了路虎店的电话,又是一顿一哭二闹三上吊,你去了旁边的玛莎拉蒂店下了订单。
整体的流程如下:


为啥明明已经锁定了薪酬,可是收入却仍然无情的增长。
原因很简单,你只锁定住了既有的数据,来自单位的薪酬,没有锁住外界新增的数据,导致读到的数据仍然不够准确,无法做出正确的处理。这种异常场景我们称之为幻读,也就是因为新增数据导致的读不一致性。而当前的这种隔离级别称之为可重复读。也就是我们可以反复的读取之前已经读取到的数据,但是新增的数据,我们仍然可能会读取到,读不一致性仍然存在
如何解决幻读的问题呢?
答案很简单,还是加锁,之前加锁是对某些已经存在的数据加锁,现在加锁,是对全局加锁,谁要操作,谁获取到全局的锁。(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )至此也就不存在并发场景了,也就更不存在并发问题了。这种隔离级别我们称之为串行化。
至于这几种隔离级别在innodb中是如何实现的,确实是比较复杂,一两句话难以说清,我会在后文中专门讲解
下边我们总结一下前文所提到的概念:
1、 脏读
读到了其他事务未提交的数据。(也就是脏页中的数据,这个后文中我会专门讲解)
2、 不可重复读
在事务中每次读取到的数据是别人已经提交的数据,但是由于存在并发修改(update delele),每次读取到的数据不一致
3、 幻读
对于新插入的数据造成的读不一致性,我们称之为幻读
这三个问题都属于存在并发事务时,数据的前后读不一致的问题。解决办法就是通过数据库的不同隔离机制,(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )来规避掉这些问题。
1、 读未提交 Read Uncommitted
事务未提交的数据修改,对其他事务也是可见的
未解决脏读,不可重复读,幻读
2、 读已提交 Read Committed
一个事务开始后,只能看到已经提交的事务做出的修改
解决脏读,未解决不可重复读,幻读
3、 可重复读 Repeatable Read
一个事务开始后,对于已经查询出的数据,再次反复查询获取到的数据是一样的
解决了脏读,不可重复读,未解决幻读
这里要特别注意下,可重复读级别尽管不要求解决幻读问题,但是innodb存储引擎却不存在该问题,这个我会再接下来的博客中专门解释该问题
4、 串行化  Serializable
最高级别,强制事务进行串行操作
解决了所有数据库并发问题


推荐阅读
  • 本文提供了一套实用的方法论,旨在帮助开发者构建能够应对高并发请求且易于扩展的Web服务。内容涵盖了服务器架构、数据库管理、缓存策略以及异步处理等多个方面。 ... [详细]
  • 本文详细介绍了如何在Python环境中配置与Oracle数据库的连接,包括必要的软件安装和环境变量设置等步骤,旨在为初学者提供清晰的操作指南。 ... [详细]
  • 一面问题:MySQLRedisKafka线程算法mysql知道哪些存储引擎,它们的区别mysql索引在什么情况下会失效mysql在项目中的优化场景&# ... [详细]
  • 这句话是推荐使用channel来实现 让同一块内存在同一时间内只被一个线程操作的目的先看一个简单的示例代码packagemainimport(fmtnethttp)va ... [详细]
  • 本文详细介绍了如何从SVN中获取项目,并在本地环境中进行有效的构建和开发,包括具体的步骤和配置方法。 ... [详细]
  • 本文详细介绍如何在iOS项目中集成和使用KTVHTTPCache音视频缓存插件,包括Podfile配置、初始化设置及实际应用中的使用方法。 ... [详细]
  • 本文通过一个简单的 C++ 示例,深入分析了当使用 `vector::resize` 方法调整向量大小时,对象的构造函数和析构函数被调用的具体情况。示例代码展示了如何创建一个包含自定义类的对象的向量,并通过调整其大小来观察构造和析构的过程。 ... [详细]
  • Log4net是一款由Apache软件基金会开发的强大且灵活的日志记录工具,与Log4j同属一个系列。它支持多种日志记录方式,并能显著提升软件开发的效率。本文将详细介绍如何在ASP.NET Web Forms项目中集成Log4net。 ... [详细]
  • Elasticsearch集群构建指南:本地环境搭建与管理
    本文详细介绍了如何在本地环境中搭建Elasticsearch集群,包括节点配置、主节点选举机制、以及如何通过单播和广播方式增加节点。同时,文章还探讨了集群的高可用性和扩展性,以及如何通过配置防止脑裂现象的发生。 ... [详细]
  • 作为一名计算机科学专业的大三学生,我在过去的一年里自学了Visual Basic (VB),但感觉进展缓慢。VB的学习是否仅仅局限于控件的使用?如何有效地学习API?此外,有人认为Basic语言已经过时,这对VB的未来意味着什么? ... [详细]
  • 本文详细介绍了 Freemarker 模板引擎中的 include 指令,以及如何利用该指令从其他文件中引入内容,以增强页面的模块化和可维护性。 ... [详细]
  • 深入理解Kafka架构
    本文将详细介绍Kafka的内部工作机制,包括其工作流程、文件存储机制、生产者与消费者的具体实现,以及如何通过高效读写技术和Zookeeper支持来确保系统的高性能和稳定性。 ... [详细]
  • 在Ubuntu 16.04中使用Anaconda安装TensorFlow
    本文详细介绍了如何在Ubuntu 16.04系统上通过Anaconda环境管理工具安装TensorFlow。首先,需要下载并安装Anaconda,然后配置环境变量以确保系统能够识别Anaconda命令。接着,创建一个特定的Python环境用于安装TensorFlow,并通过指定的镜像源加速安装过程。最后,通过一个简单的线性回归示例验证TensorFlow的安装是否成功。 ... [详细]
  • .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了
    .NETCore中的一个接口多种实现的依赖注入与动态选择看这篇就够了最近有个需求就是一个抽象仓储层接口方法需要SqlServer以及Oracle两种实现方式,为了灵活我在依赖注入的 ... [详细]
  • 本文探讨了MySQL慢查询日志对系统性能的具体影响,以及如何利用这些日志来定位和优化执行效率低下的SQL语句。慢查询日志记录了所有超出设定时间阈值的SQL操作,这对于诊断和提升数据库性能至关重要。 ... [详细]
author-avatar
窝窝笑丫
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有