当前位置: 首页 > news >正文

事务概念

为什么80%的码农都做不了架构师?>>>   hot3.png

事务概念

我们在实际业务场景中,经常会遇到数据频繁修改读取的问题。在同一时刻,不同的业务逻辑对同一个表数据进行修改,这种冲突 很可能造成数据不可挽回的错乱,所以我们需要用事务来对数据进行管理。

什么事务?数据库中事务的四大特性:

  • 原子性(Atomicity):操作这些指令时,要么全部执行成功,要么全部不执行。只要其中一个指令执行失败,所有的指令都执行失败 ,数据进行回滚,回到执行指令前的数据状态。
  • 一致性(Consistency):事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。
  • 隔离性(Isolation):在该事务执行的过程中,无论发生的任何数据的改变都应该只存在于该事务之中,对外界不存在任何影响。 只有在事务确定正确提交之后,才会显示该事务对数据的改变。其他事务才能获取到这些改变后的数据。
  • 持久性(Durability):当事务正确完成后,它对于数据的改变是永久性的。

通俗点讲,事务就是一系列指令的集合。


并发事务导致的问题

在许多事务处理同一个数据时,如果没有采取有效的隔离机制,那么并发处理数据时,会带来一些的问题。 问题分为5类,包括3类数据读问题:脏读、不可重复读和幻读。两类数据更新问题:第一类丢失更新、第二类丢失更新。

1.脏读:一个事务读取到另一个事务未提交的更新数据。

小明的银行卡余额里有100元。现在他打算用手机点一个外卖饮料,需要付款10元。但是这个时候,他的女朋友看中了一件衣服95元  
,她正在使用小明的银行卡付款。于是小明在付款的时候,程序后台读取到他的余额只有5块钱了,根本不够10元,所以系统拒绝了
他的交易,告诉余额不足。但是小明的女朋友最后因为密码错误,无法进行交易。小明非常郁闷,明明银行卡里还有100元,怎么会 
余额不足呢?(他女朋友更郁闷。。。)

2.不可重复读:一个事务两次读取同一行的数据,结果得到不同状态的结果,中间正好另一个事务更新了该数据,两次结果相异, 不可被信任。

小明在手机上购买起购价为1W元理财产品。系统首先要判断他的余额够不够购买理财产品,如果足够再获取当前的余额,进行申请。
系统第一次读取到小明的余额还剩1W元,刚好足够购买产品。但是这个时候刚好他女朋友又看中了一个包包5000元,这次密码终于
不会再错误的女朋友毫不犹豫刷了小明的银行卡买下了这个包包。但是这个系统刚好在进行第二次确认,发现小明的余额上只有5
000元,根本不够购买。于是系统很生气,拒绝了小明的购买行为,告诉他,你真是个骗子!!!

3.虚读(幻读):一个事务读取到另一事务已提交的insert数据。

公司财务A在进行员工薪资核算业务,需要对小明的工资进行计算并录入系统,必须查询两次明细信息,然后将后一次的明细信息计
算总数出来。财务在第一次明细查询时,基本工资2000元,全勤奖1000元,提成2000元,共计5000元。在进行第二次计算时,财务
B突然接到通知,需要把下个月的节日福利也在这个月的工资中发放,每人100元。于是财务B在每个人的工资明细中又加了一条节
日福利100元。而此时财务A获得第二次查询小明的工资明细后,发现工资明细变成了4条数据,总数是5100元。两次计算结果相差
100元,财务A奇怪这多出来的一条明细100元是哪里来的呢?(都怪财务B不告诉A。。。)

注意:不可重复读和幻读的区别是:前者是指读到了已经提交的事务的更改数据(修改或删除),后者是指读到了其他已经提交事务的新增数据。 对于这两种问题解决采用不同的办法,防止读到更改数据,只需对操作的数据添加行级锁,防止操作中的数据 发生变化;二防止读到新增数据,往往需要添加表级锁,将整张表锁定,防止新增数据(oracle采用多版本数据的方式实现)。

4.第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖。

小明去银行柜台存钱,他的账户里原来的余额为100元,现在打算存入100元。在他存钱的过程中,银行年费扣了5元,余额只剩95元
。突然他又想着这100元要用来请女朋友看电影吃饭,不打算存了。在他撤回存钱操作后,余额依然为他存钱之前的100元。所以那5块钱到底扣了谁的?

5.第二类丢失更新:是不可重复读的特殊情况。如果两个事物都读取同一行,然后两个都进行写操作,并提交,第一个事物所做的改变就会丢失。

小明和女朋友一起去逛街。女朋友看中了一支口红,(对,女朋友就是用来表现买买买的)小明大方的掏出了自己的银行卡,告诉女朋友:
亲爱的,随便刷,随便买,我坐着等你。然后小明就坐在商城座椅上玩手机,等着女朋友。这个时候,程序员的聊天群里有人推荐了一本书,
小明一看,哎呀,真是本好书,还是限量发行呢,我一定更要买到。于是小明赶紧找到购买渠道,进行付款操作。而同时,小明的女朋友也
在不亦乐乎的买买买,他们同时进行了一笔交易操作,但是这个时候银行系统出了问题,当他们都付款成功后,却发现,银行只扣了小明的
买书钱,却没有扣去女朋友此时交易的钱。哈哈哈,小明真是太开心了!

为了解决上述问题,数据库通过锁机制解决并发访问的问题。根据锁定对象不同:分为行级锁和表级锁;根据并发事务锁定的关系上看:分为共享锁定和独占锁定, 共享锁定会防止独占锁定但允许其他的共享锁定。而独占锁定既防止共享锁定也防止其他独占锁定。为了更改数据,数据库必须在进行更改的行上施加行独占锁定, insert、update、delete和selsct for update语句都会隐式采用必要的行锁定。

但是直接使用锁机制管理是很复杂的,基于锁机制,数据库给用户提供了不同的事务隔离级别,只要设置了事务隔离级别,数据库就会分析事务中的sql语句然后 自动选择合适的锁。

mysql中的事务隔离级别

  • Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
  • Repeatable read (可重复读):可避免脏读、不可重复读的发生。
  • Read committed (读已提交):可避免脏读的发生。
  • Read uncommitted (读未提交):最低级别,任何情况都无法保证。

在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);而在Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别。


转载于:https://my.oschina.net/kbdxe/blog/2051799

相关文章:

  • 设计模式学习总结(一)——设计原则与UML统一建模语言
  • python生成器
  • 日志分析logstash插件介绍
  • 几句话了解Zookeeper工作原理
  • linux中辅助的一些命令
  • 大数据技术ZooKeeper应用——解决分布式系统单点故障
  • Ionic APP 热更新 之 产品发布状态下的热更新搭建,去local-dev-addon插件
  • 如何设计一个微型分布式架构?
  • [20171101]rman to destination.txt
  • java实现信息脱敏
  • Mozilla 官方博客:Firebug的寿命即将结束
  • 在Visual Studio中使用GitHub(使用篇)
  • 蜂巢科技融资6200万元,打响工业无人机平台争夺战
  • Python全栈 Web(Flask框架、变量、模板)
  • 日本RHP2机器人不仅摔倒后能自行站起来 ,还能协助人类救灾
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • ES6 学习笔记(一)let,const和解构赋值
  • express + mock 让前后台并行开发
  • gitlab-ci配置详解(一)
  • golang 发送GET和POST示例
  • Invalidate和postInvalidate的区别
  • JavaScript异步流程控制的前世今生
  • JS实现简单的MVC模式开发小游戏
  • magento2项目上线注意事项
  • MySQL主从复制读写分离及奇怪的问题
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • python docx文档转html页面
  • python_bomb----数据类型总结
  • vagrant 添加本地 box 安装 laravel homestead
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 关于Java中分层中遇到的一些问题
  • 深入浅出webpack学习(1)--核心概念
  • 树莓派 - 使用须知
  • 我的面试准备过程--容器(更新中)
  • 消息队列系列二(IOT中消息队列的应用)
  • 一天一个设计模式之JS实现——适配器模式
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​LeetCode解法汇总518. 零钱兑换 II
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (循环依赖问题)学习spring的第九天
  • (转)jQuery 基础
  • (转)大型网站架构演变和知识体系
  • (转)负载均衡,回话保持,cookie
  • .gitignore文件_Git:.gitignore
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .net core 控制台应用程序读取配置文件app.config
  • .NetCore部署微服务(二)
  • .NET下ASPX编程的几个小问题
  • /run/containerd/containerd.sock connect: connection refused
  • [ C++ ] STL---仿函数与priority_queue
  • [ 数据结构 - C++] AVL树原理及实现