- 1、创建一个名为chapter06的数据库
- 2、使用chapter06数据库
- 3、创建一个名为account的表
- 4、往表中插入数据
- 5、查询表中数据
- 6、开启一个事务然后通过update语句将a账户的100元钱转给b用户,最后提交事务。
- 7、查询表中余额
- 8、开启一个事务然后通过update语句将b账户的100元钱转给a用户
- 9、再查询表中余额
- 10、先退出MySQL数据库,再登录MySQL数据库,然后再使用chapter06数据库,在查询余额
- 11、开启一个事务然后通过update语句将b账户的100元钱转给a用户,然后使用commit语句来提交事务。
- 12、重新登录数据库然后再查询余额
- 13、开启一个事务,通过update语句将a账户的100元钱转给b账户。
- 14、然后查询A、B账户的金额;
- 15、从查询结果可以看出,a账户的100元钱转给b账户了,但是事务还没有提交,我们还可以执行事务回滚,操作如下:
- 16、查询A、B账户的余额
- 17、将b账户的隔离级别改为read uncommitted;
- 18、设置b账户事务隔离级别:
- 19、演示脏读:
- 20、在a账户中开启一个事务,并在当前窗口中执行转账功能,但不提交事务。
- 21、然后再查询余额信息
- 22将上一步开启的事务进行回滚
- 23、设置b账户中事务的隔离级别
- 24、验证是否出现脏读:
- 25、在a账户中开启一个事务,并在该事务中实现转账功能
- 26、再次查询各账户的余额信息。
- 27、演示不可重复读
- 28、在a账户中不用开启事务,直接使用update语句执行更新操作即可
- 29、查询a账户的余额
- 30、当a账户的更新语句完成后,查询b账户的余额
- 31、设置b账户中事务的隔离级别
- 32、验证是否出现不可重复读
- 33、幻读
- 34、演示幻读
- 35、验证是否出现幻读
- 36、可串行化
- 37、演示可串行化
代码:
create database chapter06;
截图:
代码:
use chapter06
截图:
代码:
create table account(
-> id int primary key auto_increment,
-> name varchar(40),
-> money float
-> );
截图:
代码:
insert into account(name,money) values
-> ('a',1000),
-> ('b',1000);
截图:
代码:
select * from account;
截图:
代码:
start transaction;
-> update account set money=money-100 where name = 'a';
-> update account set money=money+100 where name = 'b';
-> commit;
-> //
截图:
代码:
select * from account;
-> //
截图:
代码:
start transaction;
-> update account set money=money+100 where name = 'a';
-> update account set money=money-100 where name = 'b';
-> //
截图:
代码:
select * from account;
-> //
截图:
代码:
q //退出数据库 MySQL -u root -p密码 //登录数据库 use chapter06 //使用数据库 select * from account; //查询余额
截图:
从上述结果发现,事务中的转账操作没有成功,这是因为在事务转账成功后还没有提交事务就退出数据库了,由于事务中的语句不能自动提交,因此当前的操作就被自动取消了;
代码:
start transaction;
-> update account set money = money +100 where name ='a';
-> update account set money = money -100 where name ='b';
-> commit;
-> //
截图:
代码:
q //退出数据库 MySQL -u root -p密码 //登录数据库 use chapter06 //使用数据库 select * from account; //查询余额
截图:
事务的回滚:
代码:
start transaction;
-> update account set money = money -100 where name ='a';
-> update account set money = money +100 where name ='b';
-> //
截图:
代码:
select * from account;
-> //
截图:
代码:
rollback;
-> //
截图:
代码:
select * from account;
-> //
截图:
由此可以看出,以上转账的金额被取消了。
17、将b账户的隔离级别改为read uncommitted;代码:
set session transaction isolation level read uncommitted;
-> //
截图:
使用select语句查询事务的隔离级别;
代码:
select @@transaction_isolation;
截图:
为了证明出现脏读的情况,首先再b账户中开启一个事务,并在该事务中查询当前账户的余额信息。
代码:
start transaction;//开启事务 select * from account;//查询余额
截图:
代码:
start transaction;
-> update account set money = money - 100 where name ='a';
-> update account set money = money + 100 where name ='b';
-> //
截图:
代码:
select * from account;
-> //
截图:
代码:
rollback// //取消事务
截图:
将b账户中事务的隔离级别设置为read commited(读提交)
代码:
set session transaction isolation level read committed;
-> //
截图:
首先在b账户中开启一个事务,并在该事务中查询各账户的余额信息
代码:
start transaction;
-> select * from account;
-> //
截图:
代码:
start transaction;
-> update account set money = money -100 where name = 'a';
-> update account set money = money +100 where name = 'b';
-> //
截图:
代码:
select * from account//
截图;
查询各账户的余额信息
通过对比b账户设置read committed隔离级别前后,发现第二次查询数据时比第一次查询时多了一条记录,这种情况并不是错误的,但可能不符合实际条件。
需要注意的是:完成上述情况要将b账户的事务提交;
首先在b账户中开启事务,然后使用select语句查询各个账户的余额信息
从上述结果可以看出,当b账户正在事务中查询账户余额时,a账户的操作是不能立即执行的



