事务并发问题
1、脏读
又称无效数据读出。一个事务读取另外一个事务还没有提交的数据叫脏读。
例如:事务T1修改了一行数据,但是还没有提交,这时候事务T2读取了被事务T1修改后的数据,之后事务T1因为某种原因Rollback了,那么事务T2读取的就是脏数据。
2、不可重复读
同一个事务中,多次读出的同一数据是不一致的。
例如:事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便得到了不同的结果。
3、幻读
例如:事务T1插入id为3的数据,事务T2,查询不存在id为3的数据,然后t1进行了提交,事务2也执行插入id为3的,但是插入失败了已经存在了,但是查询是没有了,就会造成幻读.
注:三种问题看似不太好理解,脏读侧重的是数据的正确性。不可重复度侧重的于对数据的修改,幻读侧重于数据的新增和删除。
//创建数据库
create database test;
//创建表
CREATE TABLE User (
id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20),
age INT DEFAULT 0
);
INSERT INTO `User` VALUES (1, 'zhangsan', 23);
INSERT INTO `User` VALUES (2, 'lisi', 20);
//查询默认隔离级别
//5.7以后版本:
select @@transaction_isolation;
//5.7以前老版本:
show variables like 't%_isolation';
//修改隔离级别为读未提交
set global transaction isolation level read uncommitted;
read uncommitted
// session1 开启事务,进行一次次查询,session2,开启事务,执行:
update User set name=‘aaaa’ where id = 1;
然后没有,提交,session1再次查询,发现读到未提交的事务了,id为1的已经修改了,如图:
read committed
//修改隔离级别为不可重复读
set global transaction isolation level read committed ;
修改之后要断开连接重新开启session:
//查询默认隔离级别
//5.7以后版本:
select @@transaction_isolation;
//5.7以前老版本:
show variables like ‘t%_isolation’;
同上的操作,
// session1 开启事务,进行一次次查询,session2,开启事务,执行update查询:
update User set name=‘aaaa’ where id = 1;
select * from User;
这时候已经解决了读未提交;
然后将session2事务进行提交:
commit;
session继续查询,发现数据修改了,堵到了已经提交的数据:
session在同一个事务中,执行同一个查询确出现不同的结果:就会造成不可重复读;
repeatable read
如上的同样的操作,将事务隔离级别设置为 repeatable read ,解决了不可重复读;
set global transaction isolation level repeatable read;
update User set age=3 where id =1;
跟上面操作一样的,但是会造成,幻读:
就是如果,session1,开启事务,session2开启事务,然后session2插入一个wangwu,session1查询没有id为3的,也插入个wangwu,这时候如果session2提交了事务那么session1会插入失败,如果session2还没提交,session1会等待,session2的提交或者回滚,但是这时候session1是没有查询到的,就会造成幻读:
INSERT INTO User VALUES (3, ‘wangwu’, 20);
serializable
serializable就没什么说的了,是给整个表加锁,只有等另外事务执行完成,才能进行操作:
我在session1中开启事务,执行插入id为3的操作,这时候session2去查询User,会等待session1的事务完成…这种隔离级别基本不会用;
set global transaction isolation level serializable;
//查询默认隔离级别
//5.7以后版本:
select @@transaction_isolation;
//5.7以前老版本:
show variables like ‘t%_isolation’;