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

事务 ---- mysql

一. 引出事务

在日常开发中, 很多操作不是通过一个SQL完成的, 往往需要多个SQL配合完成

但是当多个SQL操作时, 如果中间出现了特殊的情况(程序崩溃, 系统崩溃, 网络断开, 主机掉电......), 那么可能就会出现, 前面的SQL执行成功, 后面的SQL执行失败了

考虑一个场景: 转账

如果a要给b转账500, 那么a的余额-500, b的余额+500, 那么如果在a的余额-500之后, 就出现了上述的特殊情况, 那么这个钱就消失了

这个时候就要使用到事务

二. 概念

事务, 指把多个操作, 打包成一个整体, 就能够保证, 这个整体要么都执行成功, 要么就一个都不执行, 有效避免, 部分执行, 部分未执行, 产生的一些"中间状态引起的问题"
其实, 如果中间出现问题, 并不是真的一个都没有执行, 事务中的若干个SQL必然是要一条一条执行的, 但是事务能够保证, 当执行到某一条的时候如果出现问题了, 数据库就能够自动把前面的sql造成的影响, 给恢复回去, 恢复完成, 看起来就好像一条sql都没执行的样子
像这样的"翻新"操作, 称为"回滚"(rollback)
为了实现回滚机制, 数据路在执行事务的时候, 记录日志
(数据库的日志是写入到硬盘的文件中)
当事务最终都执行完毕, 中间没有差错, 那么这些记录内容就可以不要了
但是如果执行事务的过程中, 出现问题了, mysql就可以根据日志中记录的内容, 来进行恢复操作
1)之前进行了新增操作, 就把数据删除掉
2)之前进行了删除操作, 就把数据新增回来
3)之前进行了修改操作, 就把数据改回去
4)之前进行了查询操作, 不需要任何恢复行为

三. 事务的基本特性

1. 原子性
上述把多个操作打包成一个整体, 有回滚机制, 能够出发还原的这种特性, 称为"原子性"
2. 一致性
执行事务之前和执行事务完毕之后, 数据是一致的, 不会出现对不上的情况, 其实和回滚是有关的, 一旦触发回滚了, 回滚回去的数据得是对的, 如果顺利执行没有触发回滚, 数据也是符合要求的
3. 持久性
但凡提到持久性, 就要想要: 把数据存储在硬盘上
此处的持久, 指的是程序重启/主机重启, 数据仍然存在
执行事务产生的修改, 会在硬盘上持久保存
4. 隔离性
隔离性主要考虑的是, 数据库并发执行事务时, 产生的情况
并发是指: 多个客户端, 同时给服务器, 发起事务,
此时就需要数据库服务区都能够给处理
如果同时处理, 又可能会出现问题:
1) 脏读问题
数据库中, 如果有事务A和事务B, 事务A针对某个表做出了一些修改, 但是在事务A提交之前(即事务完毕之前), 事务B就对这里的数据进行了读取, 最终就可能出现A后续的操作又把上述数据进行了修改, 导致最终B读到的数据和A提交的数据是不同的, 于是就出现了"脏读问题"
为了避免这样的情况出现, 我们可以针对 "写操作"加锁
本来是执行事务A的时候, B事务可以执行, 但是引入写加锁后, 执行A的过程中, B就不能执行了, 要等待
但是这样就相当于降低了"并发能力", 也就会降低数据库服务器的处理效率, 同时提高了"隔离性", 也提高了数据库的准确性
并发执行事务的过程中, 相互之间影响越小, 隔离性就越高, 影响越大, 隔离性就越低
2) 不可重复读问题
存在三个事务ABC, 事务A针对数据进行修改, 提交, 接下来事务B进行读取数据, 在B执行的过程中, 又有一个事务C, 又针对数据进行修改, 而此时事务B还在对数据进行读取, 就会出现前后读取的数据不一致
为了避免这样的情况出现, 我们可以针对" 读操作"加锁
本来是执行事务B的时候, C事务可以执行, 但是引入读加锁后, 执行B的过程中, C就不能执行了, 要等待
同样这样就相当于降低了"并发能力", 也就会降低数据库服务器的处理效率, 同时提高了"隔离性", 也提高了数据库的准确性
3) 幻读问题
事务A先修改并提交了数据, 事务B进行读数据, 此时事务C, 没有修改B读的数据, 但是给对应的表进行了新增数据/删除数据等操作, 导致事务B中, 读到的数据集不同, 就会出现"幻读问题"
解决幻读的方式, 是 "串行化", 时所有的事务都严格的按照"一个接一个"的方式进行, 完全没有并发了
此时执行的效率是最低的, 隔离性也是最高的, 数据也是最准确的
总结一下: 
1)脏读 ==> 写加锁
2) 不可重复读 ==> 读加锁
3) 幻读 ==> 串行化
mysql事务的隔离性具体是怎么实现呢? mysql给程序猿提供了四个隔离级别, 可以在mysql配置文件中进行设置
1) read uncommitted: 允许读取其他事务未提交的数据
2) read committed: 不允许读取其他事务未提交的数据
3) repeatable read: 针对读操作和写操作都加锁了
4) serializable(串行化): 所有事物都是串行执行的
在实际开发中, 我们要根据具体的应用场景来选择不同的隔离级别

四. 使用事务

1) 开始事务:
start transaction;
2) 回滚或提交:
rollback/commit;
例:
start transaction;
-- 阿里巴巴账户减少2000
update accout set money=money-2000 where name = '阿里巴巴';
-- 四十大盗账户增加2000
update accout set money=money+2000 where name = '四十大盗';
commit;

中间的SQL语句, 就被打包成一个整体了

相关文章:

  • 体验SmartEDA:颠覆传统,设计流程更流畅,超越Multisim与Proteus!
  • 视觉SLAM十四讲:从理论到实践(Chapter12:建图)
  • python-小游戏-弹球对决
  • 鸿蒙轻内核M核源码分析系列九 互斥锁Mutex
  • 如何查询公网IP?
  • 初级软件测试快速入门
  • 倩女幽魂游戏攻略:24小时辅助云手机选哪家好?
  • SpringBootWeb 篇-深入了解 AOP 面向切面编程与 AOP 记录操作日志案例
  • 2024年10大AI动画工具
  • 【乐吾乐2D可视化组态编辑器】实时数据,数据绑定
  • 自考搜题网?5个大学生必备的搜题 #其他#其他#媒体
  • 数据分析中的统计学基础及Python具体实现【数据分析】
  • 全栈工程师之路 — 从零到精通Spring Boot -1
  • 手机和WINDOWS电脑蓝牙连接后怎样放歌,无法选择媒体音频 蓝牙媒体音频勾选不上
  • linux系统使用达梦数据库
  • 【刷算法】求1+2+3+...+n
  •  D - 粉碎叛乱F - 其他起义
  • input的行数自动增减
  • leetcode386. Lexicographical Numbers
  • Phpstorm怎样批量删除空行?
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • sublime配置文件
  • 爱情 北京女病人
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 分类模型——Logistics Regression
  • 浮现式设计
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 规范化安全开发 KOA 手脚架
  • 将回调地狱按在地上摩擦的Promise
  • 蓝海存储开关机注意事项总结
  • 判断客户端类型,Android,iOS,PC
  • 前端攻城师
  • 区块链将重新定义世界
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • ionic异常记录
  • 进程与线程(三)——进程/线程间通信
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • #162 (Div. 2)
  • (1)(1.13) SiK无线电高级配置(六)
  • (3)llvm ir转换过程
  • (笔试题)合法字符串
  • (排序详解之 堆排序)
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (已解决)什么是vue导航守卫
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • **python多态
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .net core开源商城系统源码,支持可视化布局小程序
  • .NET Core中的去虚
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET NPOI导出Excel详解
  • .NET 设计模式初探
  • .NET下ASPX编程的几个小问题