热门标签 | 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
最高级别,强制事务进行串行操作
解决了所有数据库并发问题


推荐阅读
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 推荐一个ASP的内容管理框架(ASP Nuke)的优势和适用场景
    本文推荐了一个ASP的内容管理框架ASP Nuke,并介绍了其主要功能和特点。ASP Nuke支持文章新闻管理、投票、论坛等主要内容,并可以自定义模块。最新版本为0.8,虽然目前仍处于Alpha状态,但作者表示会继续更新完善。文章还分析了使用ASP的原因,包括ASP相对较小、易于部署和较简单等优势,适用于建立门户、网站的组织和小公司等场景。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文是一位90后程序员分享的职业发展经验,从年薪3w到30w的薪资增长过程。文章回顾了自己的青春时光,包括与朋友一起玩DOTA的回忆,并附上了一段纪念DOTA青春的视频链接。作者还提到了一些与程序员相关的名词和团队,如Pis、蛛丝马迹、B神、LGD、EHOME等。通过分享自己的经验,作者希望能够给其他程序员提供一些职业发展的思路和启示。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
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社区 版权所有