Java登陆第七天——SQL之事务隔离
事务保障了每次DML操作的可靠性,即便出现了异常也可以通过回滚记录点避开异常。
并发下事务会产生的问题
会话A和会话B都进行了事务操作,并且操作的是同一个资源,在并发下会出现以下问题:
- 脏读
- 不可重复读
- 幻读
脏读
事务A读取到了事务B没有提交的数据,这就是脏读。
不可重复读
一个事务读取了两次某个数据,两次结果均不同。这就是不可重复读。
幻读
一个事务读取到了自己没有操作却存在的数据。这就是幻读。
事务隔离
mysql隔离级别定义了事务与事务之间的隔离程度。
事务隔离就是为了解决上述问题。
事务隔离级别分为以下:
- READ_UNCOMMITTED(读未提交)
- READ_COMMITED(读已提交)
- REPEATABLE_READ(可重复读)
- SERLALIZABLE(串行化)
事务隔离级别 | 脏读 | 不可重复读 | 幻读 | 加锁读 |
---|---|---|---|---|
READ_UNCOMMITTED(读未提交) | × | × | × | × |
READ_COMMITED(读已提交) | √ | × | × | × |
REPEATABLE_READ(可重复读) | √ | √ | √ | × |
SERLALIZABLE(串行化) | √ | √ | √ | √ |
事务隔离级别查看及修改
--查看当前会话的事务隔离级别
select @@tx_isolation;
--修改当前会话的事务隔离级别
SET session TRANSACTION ISOLATION LEVEL 隔离级别;
--修改系统的事务隔离级别
set global transaction isolation level 隔离级别;
--隔离级别
Read uncommitted
Read committed
Repeatable read
Serializable
准备数据
create table money (
id int primary key,
name varchar(32),
balance int
);
insert into money values (1001,'张三',2000);
insert into money values (1002,'李四',3000);
下面的事务隔离级别演示都操作的这一张表。
READ_UNCOMMITTED(读未提交)
即能够读取到没有被提交的数据,无法解决脏读、不可重复读、幻读中的任何一种,因此很少使用。
READ_COMMITED(读已提交)
即能够读到那些已提交的数据,能够防止脏读,但是无法解决不可重复读和幻读。
REPEATABLE_READ(可重复读)
默认的隔离级别。解决了脏读、不可重复读和幻读。
SERLALIZABLE(串行化)
事务隔离的最高级别,该等级的事务会对正在读写的资源进行加锁,其他会话必须等待该事务结束才能操作。