比如说一个转账操作:
现在有一个金额表(user)
现在让用户1给用户2转账100元
start transaction;#开启事务
update user set money = 400 where action = 1;
update user set money = 200 where action = 2;
commit;#事务提交
可以看到这两条SQL语句要么同时成功,要么就同时失败
设置事务的目的是:保证了多条SQL语句要么同时成功,要么同时失败;
一个事物是不可分割的工作单位,其他的操作要么同时成功,要么同时失败
start transaction;
update user set money = 400 where action = 1;
update user set money = 200 where action = 2 me;
commit;
事务的提交:
没有事务的情况下,直接进行提交修改数据;有事务则进行两阶段提交
redolog日志池 存储的是 undolog日志(一个一个的日志)
事务首先直接提交到redolog日志池 , 没问题就提交并且修改数据,如果undolog有问题,就不能进行提交了
如果数据出现未知错误,导致commit提交失败
从用户角度来看,提交日志是成功的 ;形成了undolog日志,就是提交成功了; ; ; 但是数据没有更改
造成持久性危机的是因为有一个commit,是一个两段式提交
在commit数据提交之前建一个数据缓冲池(Buffer pool),为了保证持久性,就先把undolog日志提交到数据缓冲池中,在对数据池进行定时刷脏
如果没有缓冲池,undolog日志中的数据没有问题,此时如果出现了数据库未知错误,那么数据就不会提交成功,后面未知错误解决了,数据还是不能发生改变,这条SQL语句就不会执行成功
如果有缓冲池,解决了数据库的未知错误那么缓冲池当中的undolog日志可以进行运行,数据库定时刷脏,undolog日志运行,数据就可以进行改变了
并发执行的事务不能互相干扰
假设张三和李四同时用支付宝买相同的东西
会不会出现什么问题???
假设每一个格子代表一个时间,现在让张三去查李四银行卡里的钱,而李四花一百元买零食
脏读:事务A读取到了事务B修改但是并没有提交的数据
隔离的一堵墙
到mysql的bin目录里 输入mysql -u root -p,在输入密码,在里边进行数据库sql语句的拼写
①创建一个t_user表
create table t_user(id int primary key auto_increment,username varchar(255));
②设置读未提交 read uncommitted
set global transaction isolation level read uncommitted;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;
③操作
如果在进行rollback回滚,也就是作废上边写的insert语句,但是已经读取到了insert的操作
①设置读已提交 ;read committed
set global transaction isolation level read committed;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;
②练习
解决了脏读的现象,会不会造成别的其他影响呢?
造成的影响是不可重复读
不可重复读 - - 事务A读取到的数据是事务B提交后的数据,对于事务A来说,读取数据在事务B提交之前和之后的数据是不一样的
①设置可重复读 repeatable read
set global transaction isolation level repeatable read;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;
②练习
现在出现的问题是,问题已经提交了删除数据的操作,在另一端查询还是有数据
这就是出现了幻读全部查询表
幻读:当事务A要求全部查询表当中的数据,与此同时,第二个事务B表进行了增删改操作,那么对于事务A来说,查询不到事务B的任何操作,就跟出现了幻觉一样
解决幻读 , 一般情况下不会使用
①设置串行化 - - serializable
set global transaction isolation level serializable;
查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;
②练习
一致性
事务结束时,数据完整性不会得到破坏,比如刚开始转账的时候,数据库总共600元,转账操作完成之后依然是600元
前边我们实现了原子性,持久性,隔离性,都是为了保证一致性
①事务是一个最小的,不可分割的工作单位
②一个完整的事务,需要批量的DML语句共同完成(DML语句 - - 增删改语句)
③事务只和DML语句相关(与DML一起才可以做事务)
非事务提交 - - - 一条sql语句出错,另一条SQL语句照样会执行
第二条SQL语句失败的情况,第一条SQL语句还是会执行
# 非事务提交 提交成功
update action set money = 400 where id = 1;
update action set money = 200 where id = 2;
# 非事务提交 提交不成功
update action set money = 400 where id = 1;
update action set money = 200 where id = 2 我;
如果说同时执行两条sql语句,那么其中一条能执行成功,但是另一条可能会因为其他的种种远远导致另一条语句执行失败
添加完事务,可以保证多条SQL语句要么同时成功,要么同时失败
#使用事务 提交成功
start transaction;
update user set money = 400 where action = 1;
update user set money = 200 where action = 2;
commit;
#使用事务 提交失败
start transaction;
update user set money = 400 where action = 1;
update user set money = 200 where action = 2 ;
commit;