事务隔离级别的语义:当前事务执行过程中,通过select,update,delete 操作,对其他事务的影响,反过来也是如此,通俗的说就是 当前事务是否可以看到其他事务的操作结果。
1、如何查询当前数据库的隔离级别(我们只讨论mysql的事务隔离级别)
- <span style="font-size: 10px;">select @@tx_isolation;
- SELECT @@session.tx_isolation;
- SELECT @@global.tx_isolation;
- //设置
- set tx_isolation='read-committed';</span>
2、不同隔离级别的影响
ANSI/ISO SQL标准定义了4中事务隔离级别:未提交读(read uncommitted),提交读(read committed),重复读(repeatable read),串行读(serializable)。
对于不同的事务,采用不同的隔离级别分别有不同的结果。不同的隔离级别有不同的现象。主要有下面3种现在:
1、脏读(dirty read):一个事务可以读取另一个尚未提交事务的修改数据下载。
2、不可重复读(nonrepeatable read):在同一个事务中,同一个查询在T1时间读取某一行,在T2时间重新读取这一行时候,这一行的数据已经发生修改,可能被更新了(update),也可能被删除了(delete)。
3、幻像读(phantom read):在同一事务中,同一查询多次进行时候,由于其他插入操作(insert)的事务提交,导致每次返回不同的结果集。
不同的隔离级别有不同的现象,并有不同的锁定/并发机制,隔离级别越高,数据库的并发性就越差,4种事务隔离级别分别表现的现象如下表:
隔离级别 | 脏读 | 非重复读 | 幻像读 |
read uncommitted | 允许 | 允许 | 允许 |
read committed | 允许 | 允许 | |
repeatable read | 允许 | ||
serializable | |
mysql 默认的隔离级别是:REPEATABLE-READ
注意:
1、repeatable read 允许幻读,这是ANSI/ISO SQL标准的定义要求,运行幻读依然有非常大的隐患,mysql 在repeatable read 即可满足没有幻读的要求。
2、不可重复读和幻读的区别:不可重复读的重点是修改,幻读的重点是插入或者删除了新数据。两都会造成系统错误,但是避免的方法则区别比较大,对于前者, 只需要锁住满足条件的记录,对于后者, 要锁住满足条件及其相近的记录。
举例验证:
1、建表下载
- <span style="font-size: 10px;">CREATE TABLE `t_pai` (
- `id` bigint(20) NOT NULL AUTO_INCREMENT,
- `name` varchar(10) NOT NULL,
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- PRIMARY KEY (`id`),
- KEY `idx_update_time` (`update_time`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8</span>
2、验证不存在幻读
client1 :SET autocommit= 0;
client2:SET autocommit= 0;
client1:START TRANSACTION;
client2:
START TRANSACTION;
INSERT INTO t_pai (`name`) VALUE ("2");
COMMIT;
client1:SELECT * FROM t_pai;
结果:查询不到数据:
client1:
COMMIT;
SELECT * FROM t_pai;
结果:有数据。
spring支持的隔离级别:
隔离级别 含义ISOLATION_DEFAULT | 使用后端数据库默认的隔离级别 |
ISOLATION_READ_UNCOMMITTED | 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读 |
ISOLATION_READ_COMMITTED | 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生 |
ISOLATION_REPEATABLE_READ | 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生 |
ISOLATION_SERIALIZABLE | 最高的隔离级别,完全服从ACID的隔离级别,确保阻止脏读、不可重复读以及幻读,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的 |