1、打开mysql的命令行,将自动提交事务给关闭

    1. --查看是否是自动提交 1表示开启,0表示关闭
    2. select @@autocommit;
    3. --设置关闭
    4. set autocommit = 0;

    2、数据准备

    1. --创建数据库
    2. create database tran;
    3. --切换数据库 两个窗口都执行
    4. use tran;
    5. --准备数据
    6. create table psn(id int primary key,name varchar(10)) engine=innodb;
    7. --插入数据
    8. insert into psn values(1,'zhangsan');
    9. insert into psn values(2,'lisi');
    10. insert into psn values(3,'wangwu');
    11. commit;

    3、测试事务

    1. --事务包含四个隔离级别:从上往下,隔离级别越来越高,意味着数据越来越安全
    2. read uncommitted; --读未提交
    3. read commited; --读已提交
    4. repeatable read; --可重复读
    5. (seariable) --序列化执行,串行执行
    6. --产生数据不一致的情况:
    7. 脏读
    8. 不可重复读
    9. 幻读
    隔离级别 异常情况 异常情况
    读未提交 脏读 不可重复读 幻读
    读已提交 不可重复读 幻读
    可重复读 幻读
    序列化

    4、测试1:脏读 read uncommitted

    1. set session transaction isolation level read uncommitted;
    2. A:start transaction;
    3. A:select * from psn;
    4. B:start transaction;
    5. B:select * from psn;
    6. A:update psn set name='msb';
    7. A:selecet * from psn
    8. B:select * from psn; --读取的结果msb。产生脏读,因为A事务并没有commit,读取到了不存在的数据
    9. A:commit;
    10. B:select * from psn; --读取的数据是msb,因为A事务已经commit,数据永久的被修改

    5、测试2:当使用read committed的时候,就不会出现脏读的情况了,当时会出现不可重复读的问题

    1. set session transaction isolation level read committed;
    2. A:start transaction;
    3. A:select * from psn;
    4. B:start transaction;
    5. B:select * from psn;
    6. --执行到此处的时候发现,两个窗口读取的数据是一致的
    7. A:update psn set name ='zhangsan' where id = 1;
    8. A:select * from psn;
    9. B:select * from psn;
    10. --执行到此处发现两个窗口读取的数据不一致,B窗口中读取不到更新的数据
    11. A:commit;
    12. A:select * from psn;--读取到更新的数据
    13. B:select * from psn;--也读取到更新的数据
    14. --发现同一个事务中多次读取数据出现不一致的情况

    6、测试3:当使用repeatable read的时候(按照上面的步骤操作),就不会出现不可重复读的问题,但是会出现幻读的问题

    1. set session transaction isolation level repeatable read;
    2. A:start transaction;
    3. A:select * from psn;
    4. B:start transaction;
    5. B:select * from psn;
    6. --此时两个窗口读取的数据是一致的
    7. A:insert into psn values(4,'sisi');
    8. A:commit;
    9. A:select * from psn;--读取到添加的数据
    10. B:select * from psn;--读取不到添加的数据
    11. B:insert into psn values(4,'sisi');--报错,无法插入数据
    12. --此时发现读取不到数据,但是在插入的时候不允许插入,出现了幻读,设置更高级别的隔离级别即可解决

    总结:

    1. 现在学习的是数据库级别的事务,需要掌握的就是事务的隔离级别和产生的数据不一致的情况

    后续会学习声明式事务及事务的传播特性以及分布式事务