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

事务的学习

一、什么是事务

事务 是一组操作的集合,是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销请求,这些操作要么同时成功,要么同时失败

一组操作集合,不可分割,一起向系统提交/撤销,要么同时成功,要么同时失败。

例子:

如果a向b转账100元,总共分为三个步骤
(1)检查a的手机余额是否>=100元
(1)a的手机账户钱扣掉100元
(2)b的手机账户增加100元

这三步过程合起来就是一个事务,一旦a的手机账户扣掉100元后,系统出现问题,那么b的手机账户就收不到100元,那么这100元究竟去了哪里,所以把这三步过程当作一个事务,一旦系统出现问题,那么就会将刚刚的扣钱操作撤销,也就是回滚事务,这样保证了要么一起成功,要么一起失败,不会出现100元不知道去哪了

为了解决这种问题,需要通过数据的事务来完成,业务开始时开启事务,执行完成后提交事务,一旦过程出现报错问题,就回滚事务,将数据恢复到原始状态。

你可要注意了,mysql中事务是自动提交的,执行一条语句,就会立刻提交事务。

二、事务的操作

好的下面我们就开始利用代码细致的分析一下事务操作

drop table if exists account;
create table account(
id int primary key AUTO_INCREMENT comment 'ID',
name varchar(10) comment '姓名',
money double(10,2) comment '余额'
) comment '账户表';
insert into account(name, money) VALUES ('张三',2000), ('李四',2000);

在这里插入图片描述

正常操作

# 模拟使用三条语句构成一个事务
# 正常执行完张三1900元,李四2100元-- 查询张三余额
select * from account where name='张三';-- 张三的余额减少100元
update account set money=money-100 where name='张三';-- 李四的余额增加100元
update account set money=money+100 where name='李四';

在这里插入图片描述
恢复余额操作

-- 恢复金额
update account set money=2000 where name='张三' or name='李四';

异常操作

中间插入一句报错的语句

-- 查询张三余额
select * from account where name='张三';-- 张三的余额减少100元
update account set money=money-100 where name='张三';出错误啦 你的语句出问题了
-- 李四的余额增加100元
update account set money=money+100 where name='李四';

最后卡在报错语句这个位置,余额增加的语句没有执行
在这里插入图片描述
继续回滚

-- 恢复金额
update account set money=2000 where name='张三' or name='李四';

上面的例子解决需要用到下面的方法:

控制事务1

  • 查看/设置事务提交方式
select @@autocommit;
set @@autocommit=0;
  • 提交事务
commit ;
  • 回滚事务
rollback ;

控制事务1方法修改了事务自动提交方式,改为手动提交,每次写完sql语句,需要执行commit进行一个手动的提交

利用控制事务1的方法:

-- 事务中出现报错
-- 控制事务1
-- 设置为手动提交
set @@autocommit=0;-- 查询张三余额
select * from account where name='张三';-- 张三的余额减少100元
update account set money=money-100 where name='张三';出错啦
-- 李四的余额增加100元
update account set money=money+100 where name='李四'# 出错后进行回滚事务
rollback;

一旦卡在出错啦的位置,你不提交事务(commit),此时数据库中的数据不会变化,然后你执行rollback;进行回滚操作

-- 事务中没有报错
-- 控制事务1
-- 设置为手动提交
set @@autocommit=0;-- 查询张三余额
select * from account where name='张三';-- 张三的余额减少100元
update account set money=money-100 where name='张三';-- 李四的余额增加100元
update account set money=money+100 where name='李四';commit ;

最后手动commit提交后,数据库中的数据张三余额才会变成1900,李四的余额变成2100

控制事务2

  • 开启事务
start transaction/begin;
  • 提交事务
commit ;

回滚事务

rollback;

利用控制事务2的方法:

-- 事务中出现报错
-- 开启事务
-- 控制事务2
-- 注意此时是自动提交(@@autocommit=1)
start transaction ;
-- 查询张三余额
select * from account where name='张三';-- 张三的余额减少100元
update account set money=money-100 where name='张三';出错啦
-- 李四的余额增加100元
update account set money=money+100 where name='李四';-- 异常进行回滚事务
rollback ;

由于使用了start transaction来开启一个事务,所以必须要手动的commit来提交事务,否则数据库中的数据是不会发生变化的,如果事务内部出现错误,那么就可以使用rollback来进行回滚事务

-- 事务中没有报错
-- 开启事务
-- 控制事务2
-- 注意此时是自动提交(@@autocommit=1)
start transaction ;
-- 查询张三余额
select * from account where name='张三';-- 张三的余额减少100元
update account set money=money-100 where name='张三';-- 李四的余额增加100元
update account set money=money+100 where name='李四';-- 正常提交事务
commit ;

三、事务的四大特性(ACID)

  • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
    解释:类似与刚刚转账案例,三个步骤是一个整体,要么全部失败,要么全部成功,不会出现张三的余额减少100后发生报错,导致李四的余额也没有增加,这就导致二者钱的总数与原来不一样
  • 一致性(Consistency):事务完成时,必须使所有的数据保持一致状态。 解释:也就是转账三步骤完成后,二者总的钱是不变的
  • 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行 后面会细致解析
  • 持久性(Durability):事务一旦提交或回滚,对数据库中的数据改变时永久的
    解释:由于一旦提交或者回滚后,数据就真实存放到了电脑物理磁盘中,肯定数据改变是永久

四、并发事务问题

(1)脏读:一个事务读到另外一个事务没有提交的数据
解释:例如两个并发的事务a和b,其中事务A查完数据库中的一条记录后,事务a继续修改了一条记录,此时事务A并未提交,此时并发事务b读取了事务a修改的记录,这就导致事务b读取到事务a未提交的数据

(2)不可重复读:一个事务先后读取同一条记录,但是两次读取的数据不同
解释:例如两个并发事务a和b,其中事务a读取数据库中的一条记录后,事务b对数据库的这条记录进行修改后,提交事务b,此时事务a继续读取这条记录,发现和上次读取的数据不一样

(3)幻读:一个事务按照条件查询数据,没有对应的数据行,准备插入数据时,发现这行数据存在
解释:例如两个并发事务a和事务b,其中事务a读取了id=1的数据时,发现没有这条记录,然后事务b插入id=1的数据,并且提交了事务b,此时事务a准备插入id=1的数据时发现已经存在这条数据,因为插入数据时报错,显示有这条记录

五、事务隔离级别

(1)查看事务隔离级别

SELECT @@TRANSACTION_ISOLATION;

(2)设置事务隔离级别

SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED |
READ COMMITTED | REPEATABLE READ | SERIALIZABLE }

事务隔离级别越高,数据越安全,性能越低

隔离界别脏读不可重复读幻读
read uncommitted不可避免不可避免不可避免
read committed可避免不可避免不可避免
repeatable read(默认)可避免可避免不可避免
Serializable可避免可避免可避免

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C#小结:未能找到类型或命名空间名“xxx”(是否缺少 using 指令或程序集引用?)
  • 容器docker 架构命令案例
  • 文心快码——百度研发编码助手
  • 大模型/NLP/算法面试题总结3——BERT和T5的区别?
  • WindowsMac共享文件夹设置
  • MSPM0G3507(三十六)——超声波PID控制小车固定距离
  • 景联文科技以高质量多模态数据集赋能AI大模型,精准匹配提升模型性能
  • 通用型I2C接口的应用之综合应用(N32G45XVL-STB)
  • 强化学习编程实践-4-基于蒙特卡洛的方法
  • HQL案例大全之1. 查询没有学全所有课的学生的学号、姓名(特殊:应该先连接,在筛选)
  • 鸿蒙HarmonyOS应用开发为何选择ArkTS不是Java?
  • eNSP:防火墙设置模拟公司配置(二)
  • python入门基础知识·二
  • oslo_i18n学习小结
  • LocalAI离线安装部署
  • 2017届校招提前批面试回顾
  • ESLint简单操作
  • GraphQL学习过程应该是这样的
  • HashMap ConcurrentHashMap
  • Intervention/image 图片处理扩展包的安装和使用
  • JavaScript中的对象个人分享
  • MYSQL 的 IF 函数
  • QQ浏览器x5内核的兼容性问题
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • Swoft 源码剖析 - 代码自动更新机制
  • Web Storage相关
  • windows下mongoDB的环境配置
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 关于for循环的简单归纳
  • 关于Java中分层中遇到的一些问题
  • 将 Measurements 和 Units 应用到物理学
  • 老板让我十分钟上手nx-admin
  • 前端技术周刊 2019-02-11 Serverless
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 强力优化Rancher k8s中国区的使用体验
  • 说说动画卡顿的解决方案
  • 温故知新之javascript面向对象
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • AI算硅基生命吗,为什么?
  • Android开发者必备:推荐一款助力开发的开源APP
  • Java总结 - String - 这篇请使劲喷我
  • MPAndroidChart 教程:Y轴 YAxis
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • # 数论-逆元
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (09)Hive——CTE 公共表达式
  • (7)摄像机和云台
  • (C语言)共用体union的用法举例
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)WCF的Binding模型
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (四)Controller接口控制器详解(三)
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (转)机器学习的数学基础(1)--Dirichlet分布