事务

110 阅读4分钟

事务

一.事务简介

*1. 为什么需要事务

*引入 : 例如在进行转账操作时,分三步进行 ,先从张三账户取出1000元,张三账户将减少1000元,在将1000元转账给李四,李四的账户将添加1000元,但是如果在最后一步失败,钱将原路返回,如果没有事务,将会造成没有转账成功,而张三将失去1000元,这就是事务的重要作用 。

*简单来说: 一组操作在事务范围内,要么全成功,要么全失败。(即在开启事务后,提交事务,发现报错,就会回滚事务,将数据返回但开启事务之前一样。

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

式的提交事务。

二.事务演示例题

*1. 为控制事务的情况下

这里直接截图了,节约时间~~

这是正常情况

屏幕截图 2024-01-12 112127.png

异常情况时

屏幕截图 2024-01-12 112440.png

屏幕截图 2024-01-12 122127.png

张三的钱减少,但李四的钱没有增加。需要开启事务解决这种问题。

三.控制事务

*方法一

*1.设置/查看事务

*查看事务:select @@autocommit; 显示为1 表示事务已经开启

*设置事务: set @@autucommit = 0; 0 为关闭 1 为开启

*2 提交事务

*commit;

*3回滚事务

*rollback

注意:上述的这种方式,我们是修改了事务的自动提交行为, 把默认的自动提交修改为了手动提

交, 此时我们执行的DML语句都不会提交, 需要手动的执行commit进行提交。

*方法二

*开启事务 :start transaction;

*提交事务 : commit

*3回滚事务: rollback

*上述演示例题开启事务后就会避免错误操作 屏幕截图 2024-01-12 120544.png

-- 如果正常执行完毕, 则提交事务

commit;

-- 如果执行过程中报错, 则回滚事务

-- rollback;

四.事务四大特性

*1. 原子性:事务是不可分割的最小操作单位,要么全成功,要么全失败

*2. 一致性: 事务完成时,必须使所有的/数据都保持一致状态

*3.隔离性: 数据库提供 的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行

*4. 持久性:事务一旦提交或或回滚,他对数据库的改变就是永久的

五.并发事务问题

*1.脏读 :一个事务读取到另外一个事务还没提交的数据

屏幕截图 2024-01-12 122127.png

*2. 不可重复读:一个事务读取同一条数据,但是读取的数据内容不同

屏幕截图 2024-01-12 122437.png

事务A连续读取同一条数据,但是读取的数据却不一样

*3. 幻读: 一个事务按照条件查询时没有对应的数据行,但是在插入数据时又发现了这条数据存在,这就叫做幻读

屏幕截图 2024-01-12 220541.png

事务的隔离级别

屏幕截图 2024-01-12 145640.png

可以通过事务的隔离级别解决脏读,不可重复性和幻读的问题

*1.查看事务的隔离级别: select transaction_isolation

*2. 设置事务的隔离级别: set session transaction isolation level + 隔离级别

六.并发事务的解决方法

*1. 解决脏读问题

**隔离级别在Read uncommitted情况下,会出现脏读现象,

** 例如在开启两个事物A,B,对事务B进行表操作在未提交的情况下就会修改A中表查询的数据内容

** 将隔离级别换成除**Read uncommitte任何一个级别就能解决脏读问题

*2. 解决不可重复读的问题

*隔离级别在Read uncommitted, Read committed情况下,会出现不可重复读的现象

** 例如两个事务A,B,对B进行表操作后,当B事务提交后,A事务的表数据查询时就会修改,

但是如果隔离级别设置为Repeatable Read, Serializable就可以解决不可重复读的问题,当B事务提交后,查询A事务时,数据不会进行修改,当A事务提交后,A事务在查询表时,数据会被B事务的条件修改,从而避免了不可重复读。

*3. 解决幻读问题

隔离级别必须设置为Serializable才能解决幻读问题,

** 例如在两个事务A,B中有一张表有两条数据id为1和2;在B事务中添加id = 3的数据,在A事务中查询表没有id= 3 的记录,但是在A事务中添加id= 3 的数据会显示已经存在不能添加的情况叫做幻读

** 隔离级别设置为Serializable,在A,B事务添加相同的记录时,B的事务会发生阻塞,当A的事务提交后,才会执行B事务,如果发现两个事务添加数据相同则不会进行B事务的数据添加