这是我复习时在B站上看的视频,顺便整理成笔记 视频在这
事务
事务就是DBMS当中用户程序的任何一次执行,事务是DBMS能看到的基本修改单元。
事务四大特性
原子性 (Atomicity)
原子性:无论一个事务里有多少执行步骤,这所有的步骤合起来是一个最小的执行单元,要么不做,要么全做,不存在只做到一半情况。比如银行转账,转出跟转入这两个包含在一个事务里的动作就是原子的。要么不转出也不转入,转出了就要转入。
一致性 (Consistency)
一致性是指事务使得系统从一个一致的状态转换到另一个一致状态。保证事务只能把数据库从一个有效(正确)的状态“转移”到另一个有效(正确)的状态。
理解:A向B转账100元,操作1:A账号减去100;操作2:B账号加上100,执行操作1后,进程中断,操作2没有执行,但是A的账户少了100元,B又没加上100元。从一个一致性状态到了一个不一致的状态。
隔离性 (Isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
持久性 (Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
事务隔离性进一步理解
1.read uncommitted 读未提交的
如果有事务a,和事务b
a事务对数据进行操作,在操作过程中,并没有提交,但是事务b可以看见a操作的结果
-- 创建一个user表,后续测试都要用到
create table user(
id int,
name varchar(20),
money int
);
-- 插入测试数据
insert into user values(1,'a',800);
insert into user values(2,'b',1200);
insert into user values(3,'小明',1000);
insert into user values(4,'淘宝店',1000);
-- 查询表中数据
selec * from user;
数据如下
为了达到测试效果,先修改隔离级别
set global transaction isolation level read uncommitted;
转账:小明在淘宝店买鞋子,800元
小明->广州 ATM
淘宝店->深圳 ATM
BEGIN -- 开启事务
UPDATE USER SET money=money-800 WHERE NAME='小明';
UPDATE USER SET money=money+800 WHERE NAME='淘宝店';
-- 注意这里并没有提交
小明在广州的ATM查帐
表中数据如下
于是小明给淘宝店打电话,看钱是不是到账了
淘宝店在深圳的ATM查账(另开一个查询器,查询表中数据)
发现确实到账了(读取未提交的),淘宝店开始发货
晚上去吃大餐,预算1800
结果小明rollback
rollback;
-- 再查询表
select * from user;
表中数据已经回到原来的状态了
当淘宝店去结账的时候发现余额不足
update user set money=money-1800;
-- 此时账户里只有1000元,业务不会让此操作成功
又一次查看账户
发现确实余额不足,这就是脏读
– 如果两个不同的地方,都在进行操作,如果事务a开启之后,他的数据可以被其他事务读取到
– 这样就会出现脏读
– 脏读:一个事务读到了另外一个事务没有提交的数据,就叫脏读
– 实际开发中是不允许出现脏读
2.read committed 读已提交的
修改隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
小张:银行的会计
begin
select * from user;
小张查询出来的结果,肉眼可算平均值应为1000
小张去厕所了
然后小王做了以下操作:
begin
INSERT INTO USER VALUES(5,'c',100);
commit;
select * from user;
小王插入数据更新后的结果,注意,此时小张的表是没有更新的
小张回来了
select avg(money) from user;
money的平均值不是1000,而是小王更新后的平均值
虽然我只能读到另外一个事务提交的数据,但还是会出现问题
读取同一个表的数据,发现前后不一致
不可重复读现象:read committed
3.repeatable read可重复读
修改隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
李四- -北京
begin
select * from user;
张三- -上海
begin
insert into user values(6,'d',1000);
commit;
select * from user;
李四
insert into user values(6,'d',1000);
在李四查询出来的表里没有id为6的数据,却报错,这就是可重复读的缺点,
这就现象叫幻读
事务a和事务b同时操作同一张表,事务a提交的数据事务b查看不到,就可以造成幻读
4.serializable 可串行化
SET GLOBAL TRANSACTION ISOLATION LEVEL serializable;
首先A开启事务,然后查询表中数据;B开启一个事务,执行插入操作,
而这是当A查询数据还未提交时,B的插入操作是不能执行的,等A提交后才会执行,这里还可能会出现连接超时问题而导致插入失败