|
| 1 | +# mysql事务测试 |
| 2 | + |
| 3 | +1、打开mysql的命令行,将自动提交事务给关闭 |
| 4 | + |
| 5 | +```sql |
| 6 | +--查看是否是自动提交 1表示开启,0表示关闭 |
| 7 | +select @@autocommit; |
| 8 | +--设置关闭 |
| 9 | +set autocommit = 0; |
| 10 | +``` |
| 11 | + |
| 12 | +2、数据准备 |
| 13 | + |
| 14 | +```sql |
| 15 | +--创建数据库 |
| 16 | +create database tran; |
| 17 | +--切换数据库 两个窗口都执行 |
| 18 | +use tran; |
| 19 | +--准备数据 |
| 20 | + create table psn(id int primary key,name varchar(10)) engine=innodb; |
| 21 | +--插入数据 |
| 22 | +insert into psn values(1,'zhangsan'); |
| 23 | +insert into psn values(2,'lisi'); |
| 24 | +insert into psn values(3,'wangwu'); |
| 25 | +commit; |
| 26 | +``` |
| 27 | + |
| 28 | +3、测试事务 |
| 29 | + |
| 30 | +```sql |
| 31 | +--事务包含四个隔离级别:从上往下,隔离级别越来越高,意味着数据越来越安全 |
| 32 | +read uncommitted; --读未提交 |
| 33 | +read commited; --读已提交 |
| 34 | +repeatable read; --可重复读 |
| 35 | +(seariable) --序列化执行,串行执行 |
| 36 | +--产生数据不一致的情况: |
| 37 | +脏读 |
| 38 | +不可重复读 |
| 39 | +幻读 |
| 40 | +``` |
| 41 | + |
| 42 | +| 隔离级别 | 异常情况 | | 异常情况 | |
| 43 | +| -------- | -------- | ---------- | -------- | |
| 44 | +| 读未提交 | 脏读 | 不可重复读 | 幻读 | |
| 45 | +| 读已提交 | | 不可重复读 | 幻读 | |
| 46 | +| 可重复读 | | | 幻读 | |
| 47 | +| 序列化 | | | | |
| 48 | + |
| 49 | + |
| 50 | + |
| 51 | +4、测试1:脏读 read uncommitted |
| 52 | + |
| 53 | +```sql |
| 54 | +set session transaction isolation level read uncommitted; |
| 55 | +A:start transaction; |
| 56 | +A:select * from psn; |
| 57 | +B:start transaction; |
| 58 | +B:select * from psn; |
| 59 | +A:update psn set name='msb'; |
| 60 | +A:selecet * from psn |
| 61 | +B:select * from psn; --读取的结果msb。产生脏读,因为A事务并没有commit,读取到了不存在的数据 |
| 62 | +A:commit; |
| 63 | +B:select * from psn; --读取的数据是msb,因为A事务已经commit,数据永久的被修改 |
| 64 | +``` |
| 65 | + |
| 66 | +5、测试2:当使用read committed的时候,就不会出现脏读的情况了,当时会出现不可重复读的问题 |
| 67 | + |
| 68 | +```sql |
| 69 | +set session transaction isolation level read committed; |
| 70 | +A:start transaction; |
| 71 | +A:select * from psn; |
| 72 | +B:start transaction; |
| 73 | +B:select * from psn; |
| 74 | +--执行到此处的时候发现,两个窗口读取的数据是一致的 |
| 75 | +A:update psn set name ='zhangsan' where id = 1; |
| 76 | +A:select * from psn; |
| 77 | +B:select * from psn; |
| 78 | +--执行到此处发现两个窗口读取的数据不一致,B窗口中读取不到更新的数据 |
| 79 | +A:commit; |
| 80 | +A:select * from psn;--读取到更新的数据 |
| 81 | +B:select * from psn;--也读取到更新的数据 |
| 82 | +--发现同一个事务中多次读取数据出现不一致的情况 |
| 83 | +``` |
| 84 | + |
| 85 | +6、测试3:当使用repeatable read的时候(按照上面的步骤操作),就不会出现不可重复读的问题,但是会出现幻读的问题 |
| 86 | + |
| 87 | +```sql |
| 88 | +set session transaction isolation level repeatable read; |
| 89 | +A:start transaction; |
| 90 | +A:select * from psn; |
| 91 | +B:start transaction; |
| 92 | +B:select * from psn; |
| 93 | +--此时两个窗口读取的数据是一致的 |
| 94 | +A:insert into psn values(4,'sisi'); |
| 95 | +A:commit; |
| 96 | +A:select * from psn;--读取到添加的数据 |
| 97 | +B:select * from psn;--读取不到添加的数据 |
| 98 | +B:insert into psn values(4,'sisi');--报错,无法插入数据 |
| 99 | +--此时发现读取不到数据,但是在插入的时候不允许插入,出现了幻读,设置更高级别的隔离级别即可解决 |
| 100 | +``` |
| 101 | + |
| 102 | + |
| 103 | + |
| 104 | +总结: |
| 105 | + |
| 106 | + 现在学习的是数据库级别的事务,需要掌握的就是事务的隔离级别和产生的数据不一致的情况 |
| 107 | + |
| 108 | +后续会学习声明式事务及事务的传播特性以及分布式事务 |
0 commit comments