mysql事务 作者:哇塞大嘴好帥 v1.1

mysql事务 作者:哇塞大嘴好帥

作者:哇塞大嘴好帥(哇塞大嘴好帅)

1.什么是事务?

​ 这种把多条语句作为一个整体进行操作被称为数据库事务,要不这个整体都运行成功,要不都运行失败。

2.事务原则:ACID原则

2.1原子性(Atomicity)

​ 将所有SQL作为原子工作单元(事务是最小的执行单位)执行,要么全部执行,要么全部不起作用。

做个例子:比如A账户在银行给B账户转了500万,那么B账户就接收到了500万,不可能A账户把钱转出去了B账户没有收到。也不可能A账户没有转钱B账户收到了500万

2.2一致性

​ 当我们事务没有提交的时候,我们数据库发生了宕机或者断电, 当我们再次进入数据库的时候,数据是事务操作前的数据。

​ 当我们事务提交之后,我们数据库发生了宕机或者断电,当我们再次进入数据库的时候,数据是事务操作后的数据。

总结:事务前事务后数据的完整性必须保持一致。

2.3隔离性(Isolation)

并发访问数据库的时候,一个用户的事务不能被其他事务所干扰,一个用户的事务不能被其他事务所干扰,各并发事务之间数据库是独立的

2.3.1隔离级别划分

级别 描述
Read Uncommited(读取未提交) 最低的隔离级别,允许读取未提交的数据变更,可能会导致脏读、幻读、不可重复读。
Read Committed(读取已提交) 允许读取并发事务已提交的数据,可以组织藏独,但是幻读或不可重复读仍有可能发生。
Repeatable Read(可重复读) 对同一字段的多次读取结果都是一直,除非数据是被本身事务自己修改的,可以组织藏独和不可重复读,但是幻读依然可能出现。
Serializable(可串行化) 最高的隔离界别,完全服役ACID的隔离级别,所有事务依次逐个执行,这样事务之间就完全不可能产生干扰,可以防止脏读,幻读,不可重复读。

2.3.2 脏读(Drity Read)

​ A事务还没提交B事务就读取到了A事务未提交的结果。

2.3.3 不可重复读(Non-repeateble read)

​ 在A本事务中,对自己微操作过的数据,进行了多次读取,结果发i西安了不一致或者记录不存在的情况(破坏了一致性,只有update和delete会发生)

2.3.4 幻读(Phantom Read)

​ 对自己为操作过的数据,进行了多次读取,第一次读取的时候,记录不存在,第二次读取的时候记录出现了(破坏了一致性,只有insert会导致)

2.4持久性

​ 一个事务一旦提交,它对数据库中数据的改变就是永久性的,不会因为断电宕机导致事务不生效

3.模拟隔离性

3.1 Read Uncommited

首先将数据隔离级别设置为Read Uncommited

set SESSION transaction ISOLATION LEVEL READ uncommitted
start transaction

事务A查询此test1

select *from test1
id userid mount
1 1 1111
2 2 2222
3 3 3333

事务B修改id为1的mount修改为8888再去查询

update test1 set mount = 888 where id =1;
select *from test1
id userid mount
1 1 8888

这时候事务A在去查询

select *from test1
id userid mount
1 1 8888

这时候时间B发生了某种原因进行了回滚,事务B修改8888变成最初的值1111,这时候事务A获取的数据就是脏数据

3.2 Read commited

更改事务级别

set SESSION transaction ISOLATION LEVEL READ committed;
start transaction

这时候我们事件B修改值并且没有提交

update test1 set amount  = 12 where id =1;
SELECT *from test1
id userid mount
1 1 12

事件A查询

SELECT *from test1
id userid mount
1 1 1111

如果我们进行了提交

update test1 set amount  = 12 where id =1;
commit;
SELECT *from test1

这时候事件A再去查询

SELECT *from test1
id userid mount
1 1 12

我们发现事件A没有了脏读,但是出现了一个问题,就是不可以重复读,当B事务没有提交的时候A事务查询的结果是1111,当B事务提交的时候A事务查询的结果是12.

3.3 Repeatable read

更改事务

set session TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION

这时候我们事务B进行修改

UPDATE test1 set amount = 12 where id =1;
SELECT *from test1
id userid mount
1 1 12

这时候A事务查询

SELECT *from test1
id userid mount
1 1 1111

​ 这时候A事务没有查询到脏读,而5000数据只有在他本身事件才是5000

这时候把事务B提交

commit;
SELECT *from test1
id userid mount
1 1 12

这时候我们A事务再去查询

SELECT *from test1
id userid mount
1 1 1111

我们发先仍然是1111,这就说明了多次查询结果他是一致性的,也就是可重复读的。但是他会存在幻读

这时候我们在B事务插入一个数据并且提交事务查询

insert into test1 VALUES(4,4,4444);
commit;
SELECT *from test1
id userid mount
1 1 1111
2 2 2222
3 3 3333
4 4 4444

这时候事务A再去查询

SELECT *from test1
id userid mount
1 1 1111
2 2 2222
3 3 3333

这是我们就在A事务插入数据

insert into test1 VALUES(4,4,4444);

会发现它报错了主键冲突因为我们id是主键,这时候就产生了幻读。设置Serializable就好了

3.4 Serializable

​ 解决一切

3.5 对比

事务隔离级别 脏读 不可重复读 换读
Read-uncommitted(读未提交)
Read-committed(读取已提交) 不会
Repeatable-read(可重复读) 不会 不会
Serializable(串行化) 不会 不会 不会

这四个级别只是一个标准们个个数据库厂商,并不是完全按照着这个规则来的

你可能感兴趣的:(Mysql,mysql,数据库,sql)