【数据库】事务

第八章 事务


文章目录


前言

事务就是针对一组SQL,呈现的效果是要么都不执行,要么全都执行 .

其中的机制是靠回滚,运行过程中会对上述增删改查操作记录一个日志~~

  • 如事务正常执行日志就会删除
  • 如执行到一半出现故障,再次启动的时会查询日志内容,并根据做的操作把保存的数据还原回去,恢复如初

一、 事务的ACID特型

这里需要背下来!!!

  1. Atomicity(原子性) :

    把多个SQL打包成一个整体 . 要么全都执行完,要么一个都不执行.

    (一个都不执行是通过回滚机制实现的,不是真没执行,而是通过回滚,还原成

    最初的状态了)

  2. Consistency(一致性) :

    一个事务,执行前和执行后,数据得是合理的,靠谱的~~(事务的执行不能破坏数据的完整性)

  3. Isolation (隔离性) :

    一个数据库服务器可以同时执行多个客户端提交的事务~~并且这些事务之间产生的影响尽量小

    (隔离性非常重要 , 下面会单独讲解)

  4. Durability(持久性):

    事务对于数据库做出的修改,都是"持久的"数据保存在硬盘上.重启服务器,重启数据库,都不会使数据丢失~~


二、如何使用事务

开启事务

start transaction;

回滚 :

rollback;

保存点 : (可以回滚到到保存点)

savepoint 名字1;

回滚到保存点 :

rollback to 名字1 ;

提交事务 : (已经提交过的就不能回滚了)

commit ;


三、事务的隔离性和隔离级别

事务具有隔离性 , 不同的隔离程度 , 称为事务的隔离级别

有四种 :

  1. READ UNCOMMITTED , 读未提交
  2. READ COMMITTED , 读已提交
  3. REPEATABLE READ , 可重复读 (默认级别)
  4. SERIALIZABLE , 串行化

不同隔离级别存在不同问题 , 如 脏读 , 不可重复读 , 幻读

隔离级别 脏读 不可重复读 幻读
READ UNCOMMITTED
READ COMMITTED 没有
REPEATABLE READ 没有 没有
SERIALIZABLE 没有 没有 没有

从上往下` , 隔离力度(安全性)越来越高 , 并发性越来越弱


四、查看和修改隔离型

这些语句不用背下来 , 到时候查就可以~~

查看隔离级别 :

SELECT @@GLOBAL.transaction_isolation ;

修改隔离级别语句 :

SET GLOBAL transaction_isolation = ' 隔离级别 ' ;

一般实际开发中不会这么做 , 这种设置方式只是临时的 , 真正是通过配置文件来修改的


五、不同隔离级别存在的问题

以下为示范 , 如更改隔离级别后自行操作时未能达到期望效果 , 可尝试把连接2断开重连

1. 脏读

隔离级别 :读未提交 READ UNCOMMIT

连接1 : 开启事务 , 修改数据但不提交

连接2 : 开启事务 , 连接1中的修改的数据还没有提交 , 但查询到的结果为修改后的


解决脏读

提升隔离级别 : 读已提交 READ COMMITE

连接1 : 开启事务 , 更改 id=4

连接2 : 连接1中没有commit , 此处查询到的仍是修改前的数据 , 没有脏读


2. 不可重复读

隔离级别 : 读已提交 READ COMMITTED

连接2 : 查询 str9

连接1 : 修改数据并提交

连接2 : 再次查询 , 读到的结果和第一次不一样


解决不可重复读

提升隔离界别 : 可重复读 REPEATABLE READ

连接2 : 开启事务 , 并查询 str9

连接1 : 修改数据并提交

连接2 : 再次查询 , 结果与第一次相同


3. 幻读

隔离级别 : 不可重复读 REPEATABLE READ

连接2 : 开启事务并查询

连接1 : 新增数据并提交

连接2 : 再次查询 , 没有出现幻读 , 因为可重复读隔离级别本身已经能处理大部分幻读情况

那怎么让它出现呢 ? str3 中id为主键不可重复 , 因此我们新增连接1中插入的 id 看看能不能成功~~

失败了 , 内置查询会发现这个数据已经存在 , 我们称这也相当于幻读


解决幻读问题

提升隔离级别 : 串行化 SERIALIZABLE

连接2 : 开启事务并查询

连接1 : 进行插入 ,发现并没有成功 , 连接2事务没有执行完 , 连接1事务只能等 , 一段时间之后就会失败~~

连接2 : 重新开启一个事务

连接1 : 也开启一个事务 , 并进行插入 , 发现指令没有立刻执行

连接2 : 插入一行相同的数据并提交

连接1 : 开始执行了 , 但因为 id 为主键插入失败


总结

哇 , 终于要学完数据库了 , 加油 !!!

相关推荐
vHelios9 小时前
【电商项目】短信测试遇到的问题与解决方案:InaccessibleObjectException报错、单元测试通过但未接收到验证码
java·微服务
盟道科技10 小时前
小程序电商订单超时自动取消的三种实现方案:定时扫描、Redis 过期监听、延迟消息对比与生产落地
数据库·redis·小程序
气泡水好喝10 小时前
Java魔法探秘:从Java代码到CPU指令,一个方法调用的完整生命周期
java
气泡水好喝10 小时前
读《阿里巴巴Java开发手册》五年,这7条规约救了我太多次
java
剑锋所指,所向披靡!10 小时前
MySQL存储引擎
数据库·mysql
凯哥Java10 小时前
System.setProperty 的正确姿势:Spring Boot 启动类里的“缺省值“魔法
java·spring boot·后端
reasonsummer10 小时前
【办公类-146-05】20260901《一分园、二分园四大教育》(优化版:标题excle+复制AI文字+Python占位符录入)
开发语言·数据库·c#
lhldsg10 小时前
智慧场馆解决方案小程序系统:从架构设计到落地实践
java·小程序·需求分析
2301_8009549910 小时前
关系型数据库与非关系型数据库详解
数据库·nosql
崖边看雾10 小时前
MySQL——SQL 经典练习题:学生选课成绩查询(附详细注释)
大数据·数据库·sql·mysql