事务
一.事务简介
*1. 为什么需要事务
*引入 : 例如在进行转账操作时,分三步进行 ,先从张三账户取出1000元,张三账户将减少1000元,在将1000元转账给李四,李四的账户将添加1000元,但是如果在最后一步失败,钱将原路返回,如果没有事务,将会造成没有转账成功,而张三将失去1000元,这就是事务的重要作用 。
*简单来说: 一组操作在事务范围内,要么全成功,要么全失败。(即在开启事务后,提交事务,发现报错,就会回滚事务,将数据返回但开启事务之前一样。
*注意: 默认MySQL的事务是自动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐
式的提交事务。
二.事务演示例题
*1. 为控制事务的情况下
这里直接截图了,节约时间~~
这是正常情况
异常情况时
张三的钱减少,但李四的钱没有增加。需要开启事务解决这种问题。
三.控制事务
*方法一
*1.设置/查看事务
*查看事务:select @@autocommit; 显示为1 表示事务已经开启
*设置事务: set @@autucommit = 0; 0 为关闭 1 为开启
*2 提交事务
*commit;
*3回滚事务
*rollback
注意:上述的这种方式,我们是修改了事务的自动提交行为, 把默认的自动提交修改为了手动提
交, 此时我们执行的DML语句都不会提交, 需要手动的执行commit进行提交。
*方法二
*开启事务 :start transaction;
*提交事务 : commit
*3回滚事务: rollback
*上述演示例题开启事务后就会避免错误操作
-- 如果正常执行完毕, 则提交事务
commit;
-- 如果执行过程中报错, 则回滚事务
-- rollback;
四.事务四大特性
*1. 原子性:事务是不可分割的最小操作单位,要么全成功,要么全失败
*2. 一致性: 事务完成时,必须使所有的/数据都保持一致状态
*3.隔离性: 数据库提供 的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
*4. 持久性:事务一旦提交或或回滚,他对数据库的改变就是永久的
五.并发事务问题
*1.脏读 :一个事务读取到另外一个事务还没提交的数据
*2. 不可重复读:一个事务读取同一条数据,但是读取的数据内容不同
事务A连续读取同一条数据,但是读取的数据却不一样
*3. 幻读: 一个事务按照条件查询时没有对应的数据行,但是在插入数据时又发现了这条数据存在,这就叫做幻读
事务的隔离级别
可以通过事务的隔离级别解决脏读,不可重复性和幻读的问题
*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事务的数据添加