这是一个真实的故事
Session A | Session B |
---|---|
start transaction; | |
start transaction; | |
select name from user where id = 1; //liunim | |
update user set name =’liunim_modified’ where id = 1; | |
commit; | |
select name from user where id = 1; //liunim | |
commit; |
这就是数据库事务隔离级别跟我的第一次过招场景。
原因: 数据库的事务隔离级别被设置为REPEATABLE-READ,导致Session A对数据的修改不能被Session B中已经开启的事务读取到。
数据库系统的事务
-
数据库系统的事务应遵循ACID原则:
-
原子性(Atomicity)
对数据库操作的原子单位就是事务,同一个事务内的数据库操作(也就是sql语句)要么全部成功,要么全部失败。
-
一致性(Consistency)
在事务提交以前数据库中的所有数据满足所有的约束,在事务提交以后数据库中的所有数据也要满足所有的约束。
-
隔离性(Isolation)
每个事务的执行是独立的,事务的执行过程中彼此不受影响。
-
持久性(Durabilily)
一旦事务提交,对数据库进行的操作就要永久的保留下来。
原子性
一致性
隔离性
Mysql事务隔离级别
四种隔离级别
- READ-UNCOMMITED
当一个session的事务隔离级别被设置为读未提交时,该session创建的事务中的查询语句可以读取到其他session开启的事务里面对数据进行的更改,即使事务未提交。
测试时候注意 连接被重置以后 之前设置的 事务隔离级别 以及关闭掉的自动提交均会恢复至默认值。
(此隔离级别会出现 读脏、不可重复读、幻读)
- READ-COMMITED
事务隔离级别为读已提交的事务中,可以读取到其他事务提交的对数据的修改,也就是说在同一个事务中多次读取同一条数据,会得到不同的值(在此期间有其他事务对该数据进行修改,并且提交)。
(此隔离级别会出现 不可重复读、幻读)
- REPEATABLE-READ
mysql InnoDB引擎默认的事务隔离级别,可重复读是指的在同一个未提交的事务中每次读取到的同一条数据的值是不变的。不变是相对于事务开启的那一刻的值不变。也就是说事务的隔离级别为可重复读的情况下,事务中的任何语句感知不到其他事务对同一条数据进行的修改,即使其他事务已提交。
带有 for update的查询例外 他可以读取到已提交的数据。可重复读只针对查询。
(此隔离级别会出现 幻读)
- SERIALIZABLE
查看&设置隔离级别
查看系统级隔离级别、会话级的事务隔离级别:
select @@global.tx_isolation,@@tx_isolation;
设置隔离级别:
set session tx_isolation='read-uncommitted'; //session级别
set global tx_isolation='read-uncommitted'; //系统全局
Oracle事务隔离级别
暂时还未接触,敬请期待……
SqlServer事务隔离级别
暂时还未接触,敬请期待……