![](https://i-blog.csdnimg.cn/direct/0a79413cc78d4d338abfc92d25022401.png)
一 事务简介,
![](https://i-blog.csdnimg.cn/direct/0874f61c6038413e981587019389d5b6.png)
数据库准备:
create table account(
id int auto_increment primary key comment '主键ID',
name varchar(128) not null comment '姓名',
backaccountnumber char(18) unique comment '银行账号',
money float comment '余额'
)comment '银行账号表';
#drop table account;
insert into account
values (null,'张三','123412341234123412',2000),
(null,'lisi','123412341234123413',8000),
(null,'wangwu','123412341234123414',9000);
二 事务操作,
由于mysql 默认的一条一条sql语句都是 默认开启事务的。
当我们执行三条sql语句的时候,1,2都成功了,但是3失败了,就会造成问题
这三条sql语句是:张三给李四的账号转1000块
1.查询张三的账号的钱 大于1000块
- 张三money = money-1000;
3, 李四money = money +1000;
事务的操作的两种方式
select @@autocommit;
set @@autocommit = 0;
select * from account where name = '张三';
update account set money = money-1000 where name = '张三';
update account set money = money+1000 where name = 'lisi';
commit ;
rollback ;
![](https://i-blog.csdnimg.cn/direct/668fcf7369ba47d8ade5585c30cbce02.png)
start transaction ;
select * from account where name = '张三';
update account set money = money-1000 where name = '张三';
update account set money = money+1000 where name = 'lisi';
commit;
rollback ;
![](https://i-blog.csdnimg.cn/direct/97b5d361d8184b7ba638cd9a7dc9c550.png)
三 事务四大特性,
![](https://i-blog.csdnimg.cn/direct/6da58e35c1254e1eaf423e1a1fe7f761.png)
四 并发事务问题,
并发事务问题:指的是 A 事务 和 B事务 在同时 操作某一个章表的时候,发生的问题。
![](https://i-blog.csdnimg.cn/direct/687dc287477c459fa02ad167b9f8090c.png)
脏读
事务A 有三步:
start transaction ;
-
select money from account where id =1; # 查询 id 为1的银行账户
-
update account set money = money+30000 where id = 1; #工资发了3万
-
update account set money = money+80000 where id = 1; # 奖金发了8万
commit;
事务B 也有三步:
start transaction ;
-
select money from account where id =1; # 查询 id 为1的银行账户
-
update account set money = money-10000 where id = 1; #买了个华为手机
-
update account set money = money-30 where id = 1; # 吃了个中午饭
commit;
脏读发生的时机:事务B 读取到了 事务A 还没有commit的数据
当事务A 执行了第一步和第二步的时候,注意,这时候事务A 还没有提交
这时候事务B 执行了第一步,查询,会看到 账户已经加了3万块钱了
这个就是脏读
![](https://i-blog.csdnimg.cn/direct/1b39e761d28c48578f0a17f67ada45c7.png)
不可重复读
一个事务先后读取同一个数据,但是第一次 和 第二次 读取到的数据不同。
![](https://i-blog.csdnimg.cn/direct/0299cf3c001747508108c989fd69f8d5.png)
事务A 有4步:
start transaction ;
-
select money from account where id =1; # 查询 id 为1的银行账户,发现值是1000
-
......
(这时候事务B 执行完3步后,提交了)
-
select money from account where id =1; # 查询 id 为1的银行账户,发现值是2000
-
.......
commit;
事务B 有三步:
start transaction ;
-
select money from account where id =1; # 查询 id 为1的银行账户
-
update account set money = 1000 where id = 1; #钱变成了1000
-
select money from account where id =1; # 查询 id 为1的银行账户
commit;
幻读
![](https://i-blog.csdnimg.cn/direct/743cf762908a4d2880ce944568440c29.png)
五 事务隔离级别
那么前面遇到的 并发事务问题,应该怎么解决呢? 通过 设置 事务隔离级别 就可以解决。
![](https://i-blog.csdnimg.cn/direct/79b7faf1835c411d84ea6d8da939ec60.png)
# 查看当前 事务级别 是啥
select @@transaction_isolation;
# 设置 事务级别 session 代表会话级别的,只是对当前窗口有效; global 代表全局生效,即当前窗口和其他窗口都生效
set session transaction isolation level read uncommitted ;
set session transaction isolation level read committed ;
set session transaction isolation level repeatable read ;
set session transaction isolation level serializable ;
六 总结
![](https://i-blog.csdnimg.cn/direct/a10a086d553949babb650936e51b5322.png)