Mysql|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事务 作者(哇塞大嘴好帥 v1.1)】? 这四个级别只是一个标准们个个数据库厂商,并不是完全按照着这个规则来的

    推荐阅读