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

数据库事务及其原理

一.什么是事务

事务简单说将一串操作看成一个整体,只有当这串操作全部执行成功的时候才成功,只有有一个操作出错就失败,回滚到操作开始之前。这一串操作就是事务。

比如张三给李四转账100块这件事有三个步骤,
查询张三余额,张三自己账户先扣一百块,然后李四账户获得一百块。
如果张三扣款成功,但李四获得一百块失败,那么不是转账失败,凭空损失了100块?或者张三扣款失败,但李四获得一百块成功,那张三不是凭空赚了100块?
然后我们将这两个事情打包,规定有一件事情做错就代表失败并回滚到最初的状态,就保证了数据的一致性,解决了上面的问题。

注意: 默认MySQL的事务是自动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐 式的提交事务。简单说其实一条DML也有事务。

二.如何添加事务

除了上面的默认单条语句会隐式加上事务,我们也可以显示为一系列SQL语句加上事务。

-- 开启事务
start transaction
-- 1. 查询张三余额
select * from account where name = '张三';
-- 2. 张三的余额减少1000
update account set money = money - 1000 where name = '张三';
-- 3. 李四的余额增加1000
update account set money = money + 1000 where name = '李四';
-- 如果正常执行完毕, 则提交事务
commit;
-- 如果执行过程中报错, 则回滚事务
-- rollback;

三.事务四大特性【ACID】

原子性(Atomicity):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
一致性(Consistency):执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
隔离性(Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
持久性(Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
上述就是事务的四大特性,简称ACID。

四.事务并发问题

 (1)丢失修改 -- 两个或多个事务同时读取同一数据并进行更新时,其中一个事务的更新结果被另一个事务的更新覆盖,导致前一个事务的修改丢失。

(2)赃读 -- 一个事务读取了另一个事务尚未提交的修改数据,而后者可能会回滚导致数据不一致。

脏读会让事务读取到不正确的中间状态数据。

(3)不可重复读 -- 一个事务内多次读取同一数据时,由于其他事务的修改或提交,导致每次读取的结果不同。

(4)幻读:一个事务先后查询同一条记录,刚开始没有查询到对应的数据行,但是另一个事务在这过程中插入数据,然后再次查询,又发现这行数据已经存在,好像出现了 "幻影"。

总结

丢失修改就是类似经典竞态问题,多个线程修改导致最终修改后的数据不一致
脏读就是因为rollback造成的前后读取数据不一致
不可重复度是因为update造成的前后读取数据不一致
幻读是因为insert和delete造成的前后读取数据不一致

丢失修改是修改后的数据不正确,其他是因为各种因为其他线程各种原因的修改导致的前后读取的数据不正确。

五.事务隔离级别

【1】为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别。主要有以下几种:

SQL 标准定义了四个隔离级别:

READ-UNCOMMITTED(读取未提交) :最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
READ-COMMITTED(读取已提交) :允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
REPEATABLE-READ(可重复读) :对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
SERIALIZABLE(可串行化) :最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

怎么记呢?

读取未提交就是防止丢失修改
读取已提交就是进一步防止rollback,从而防止脏读
可重复读就是进一步防止update,从而防止不可重复读
可串行化就是进一步防止insert和delete,从而防止幻读

【2】在mysql中可以使用下面的查看和设置事务隔离级别。

SELECT @@TRANSACTION_ISOLATION; # 查看事务隔离级别
SELECT @@transaction_isolation; # mysql8.0修改了上面的命令语法


SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }#设置事务隔离级别

在Mysql中默认是可重复读,其他数据库很多都默认是读取已提交。

【3】但是需要注意,事务隔离级别越高,数据越安全,但是性能越低。

六.原理

TODO


http://www.kler.cn/a/405451.html

相关文章:

  • OpenCV 计算图像清晰度
  • SpringBoot提交参数去除前后空格
  • 五天SpringCloud计划——DAY1之mybatis-plus的使用
  • 嵌入式Linux的RTC读写操作应用
  • 基于大数据爬虫数据挖掘技术+Python的网络用户购物行为分析与可视化平台(源码+论文+PPT+部署文档教程等)
  • Altenergy电力系统控制软件 status_zigbee SQL注入漏洞复现(CVE-2024-11305)
  • shell脚本启动springboot项目
  • vscode利用ofExtensions插件可以调试单进程Openfoam,但是不能调试mpi多进程案例
  • “软件定义汽车”时代 | 产线海量数据刷写解决方案
  • 【Spark】【大数据技术基础】课程 实验七 Spark基础编程实验
  • Linux|进程程序替换
  • 【PGCCC】B+Tree 的并发优化 BLink-Tree
  • 解锁电商新境界:1688 API接口实战指南——商品详情与关键字搜索全攻略
  • 神经网络12-Time-Series Transformer (TST)模型
  • GoZero接口用postman调用字段类型不够并优化:如何解决数据库插入与更新失败问题
  • 用CAXA CAD电子图板导入图框、标题栏并导出pdf的方法
  • Dubbo HTTP接入之triple协议
  • 了解量子技术:一场科技革命的前夜
  • 【bug】使用transformers训练二分类任务时,训练损失异常大
  • HarmonyOs鸿蒙开发实战(21)=>组件间通信@ohos/liveeventbus
  • vue2 + iview(view-design) 中封装使用 vxe-table 处理表格渲染大量数据卡顿现象
  • 后端返回二进制流前端导出下载excel文件
  • Vue 项目中如何使用FullCalendar 时间段选择插件(类似会议室预定、课程表)
  • VMware虚拟机Ubuntu桥接模式突然连接不上网络解决办法
  • 类文件结构详解.上
  • Linux-Apache静态资源