六、事务-2.事务操作

解决问题:要把转账的三步操作控制在一个事务之内

当前每一个SQL语句就是一个事务,默认MySQL的事务是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务。

一、方式一:修改当前窗口事务提交方式

1、概念

手动提交——

输入SQL代码,点执行按钮,accout表刷新不会生效;

必须输入SQL代码,点执行按钮,再输入commit代码并运行commit行,account表刷新才会生效。

2、正常场景演示

1)恢复数据到初始状态2000

2)查看当前数据库的事务提交方式

1表示自动提交,0表示手动提交

3)修改事务提交方式为手动提交——只对当前窗口有效

4)执行三步转账代码

控制台看到三条代码都已执行完毕:

account表刷新,2000数据不变:(因为未执行commit操作)

5)提交事务

account表刷新,转账操作生效:

3、异常场景演示

 1)恢复数据到初始状态2000

记住此时事务为手动提交,必须要commit才能生效!!

2)执行三步转账代码(异常)

控制台看到第一条和第二条代码执行成功,第三条代码异常:

此时,不要commit操作,数据库就不会影响。(commit的话,张三变1000,李四还是2000)

3)回滚事务

account表刷新,数据回滚到原来的值:

二、方式二:不修改事务提交方式,针对局部代码开启手动提交

1、概念

2、异常场景演示

1)恢复原样:

事务提交方式置为1:自动提交

数据恢复初始状态2000

2)开启事务(手动提交)

抛出异常,不能提交事务commit,要回滚事务rollback。

此时,表中数据没有真正生效,还是2000。(只有start transaction没有commit)

3)回滚事务

 account表刷新,数据回滚到原来的值:

【代码】

- -------------------------------- 事务操作 --------------------------------
-- 数据准备
create table account(
    id int auto_increment primary key comment '主键ID',
    name varchar(10) comment '姓名',
    money int comment '余额'
) comment '账户表';
insert into account(id, name, money)
values (null, '张三', 2000),
       (null, '李四', 2000);

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

-- 方式一
select @@autocommit;   -- 返回1:自动提交。    返回0:手动提交。
set @@autocommit = 0;    -- 设置为手动提交(只对当前窗口有效)
-- 方式二
start transaction ;

-- 转账操作(张三给李四转账1000)
-- 1、查询张三账户余额
select * from account where name = '张三';
-- 2、将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
程序抛出异常...
-- 3、将李四账户余额+1000
update account set money = money + 1000 where name = '李四';

-- 提交事务
commit ;
-- 回滚事务
rollback ;