🎄概念
- 事务是一组操作的集合,它是一个不可分割的工作单位,事务会将所有的操作作为一个整体一起向系统提交或者撤销。
- 即事务要么同时成功,要么同时失败
⭐示例
- 张三给李四转账 1000 块钱,张三银行账户的钱减少 1000 ,而李四银行账户的钱要增加1000 。 这一组操作就必须在一个事务的范围内,要么都成功,要么都失败。
正常情况: 转账这个操作, 需要分为以下这么三步来完成 , 三步完成之后, 张三减少1000, 而李四
增加 1000, 转账成功 :
- 查询张三账户余额
- 张三账户余额-1000
- 李四账户余额+1000
异常情况:如果再第三步出现了异常,这就导致张三银行卡里的钱被扣掉了,但是李四银行卡里的前并没有增加。造成数据不一致。
- 为了解决这种问题,就需要再这个转账的业务开始之前开启事务,执行完毕后提交事务,如果再执行过程中有任何一步报错,那么就回滚事务,也就是把数据恢复到开启事务之前的状态。
🎄事务操作
📢对于MySQL以及很多数据库的事务都是默认开启的,也就是每次执行一条语句它都会进行隐式的事务提交。
⭐数据准备
- 首先准备一个账户表,并插入两条用户信息。
sql">create table account (id int primary key auto_increment comment 'ID',name varchar(10) comment '姓名',money double(10,2) comment '余额'
)comment '账户表'insert into account values (null,'张三',2000),(null,'李四',2000)
⭐未控制事务
📢测试正常情况
- 查询张三余额: select money from account where name = '张三'
- 张三余额减1000: update account set money = money - 1000 where name = '张三'
- 李四余额增加1000:update account set money = money + 1000 where name = '李四'
- 这时候检查数据的状态,发现操作后数据是一致的。
📢测试异常情况
- 首先把数据都恢复到初始状态,即都为2000
- 此时模拟第二条语句执行失败的情况。将这条语句的查询条件写错。
select money from account where name = '张三'; update account set money = money - 1000 where nam = '张三'; update account set money = money + 1000 where name = '李四';
- 这时候查询数据,发现张三的账户金额并没有改变,但是李四的金额增加了,这就造成了前后数据不一致。
⭐控制事务一
- 这种方式,我们是修改了事务的自动提交行为 , 把默认的自动提交修改为了手动提交 , 此时我们执行的 DML 语句都不会提交 , 需要 手动 的执行 commit 进行提交。
📢查看事务的提交方式
sql">select @@autocommit
- 如果发现事务的提交方式是1,那就是自动提交,如果是0那就是手动提交。
- 我们可以通过更改默认的提交方式来控制事务。
sql">set @@autocommit = 0;
📢提交事务
- 当确认本次操作的所有语句都执行成功后,就可以提交事务了。
sql">commit
📢回滚事务
- 如果发现有操作执行失败,那么需要回滚事务,让本次操作的内容全部恢复到原始状态。
sql">rollback
- 对于这种设置方式来说,只有在当前操作的会话窗口有效,在别的窗口是默认提交方式还是没有改变的。
- 我们现在执行上面的两条都成功的操作
sql">update account set money = money - 1000 where name = '张三';
update account set money = money + 1000 where name = '李四';
- 此时我们发现表里的数据实际是不会变化的,这时候需要手动commit来提交。
- 这时候发现数据就被更新了。
sql">commit
- 这时候可以测试一下失败的情况
sql">update account set money = money - 1000 where nam = '张三';
update account set money = money + 1000 where name = '李四';
-
此时当我们发现第一条sql执行失败了,我们不能进行commit提交,而是应该使用rollbak进士回滚,让数据恢复到之前的状态。
sql">rollback
⭐控制事务二
📢开启事务
sql">START TRANSACTION 或 BEGIN ;
📢提交事务
- 执行正确的业务操作。
sql">update account set money = money - 1000 where name = '张三';
update account set money = money + 1000 where name = '李四';
-
此时数据库数据还没有更新我们需要手动提交
sql">commit
📢回滚事务
- 执行错误的业务操作
- 这里第一条更新语句失败,但第二条更新语句成功,此时我们rollback,这时候数据库不会被更新。
sql">begin
update account set money = money - 1000 where nam = '张三';
update account set money = money + 1000 where name = '李四';
rollback
🎄重点注意
📢如果上一个事务我们没有rollback和commit然后直接begin开启了下一个事务,这时候未提交的事务会被主动提交。