事务性质和隔离级别详解
2018-05-18 20:10
357 查看
事务定义
数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。维基百科事务性质 ACID
原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行
持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中
事务隔离级别
SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。维基百科未提交读 [READ UNCOMMITTED]
提交读 [READ COMMITTED]
可重复读 [REPEATABLE READ]
可序列化 [Serializable]
默认隔离级别
不同的DBMS[database management system]默认隔离级别也不同。大多数据库允许用户设置隔离级别。有些DBMS在执行一个SELECT语句时使用额外的语法来获取锁(如SELECT ... FOR UPDATE来获得在访问的数据行上的排他锁)。隔离级别 vs 读现象
隔离级别 | 脏读 | 不可重复读 | 幻影读 |
---|---|---|---|
未提交读 [READ UNCOMMITTED] | 可能发生 | 可能发生 | 可能发生 |
提交读 [READ COMMITTED] | - | 可能发生 | 可能发生 |
可重复读 [REPEATABLE READ] | - | - | 可能发生 |
可序列化 [Serializable] | - | - | - |
隔离级别数据测试
MySQL 默认隔离级别mysql> select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | **REPEATABLE-READ** | +-----------------+ 1 row in set (0.01 sec)
自动提交关闭:
mysql> show variables like 'autocommit'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | ON | +---------------+-------+ 1 row in set (0.00 sec)
修改隔离级别:
mysql>set session tx.isolation = 'READ-UNCOMMITTED';
具体测试方式:
A端操作不断改变 事务隔离级别,执行查询,B端不断进行数据更新操作
初始化数据:
use test; CREATE TABLE `t_user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID', `name` varchar(255) DEFAULT '' COMMENT '姓名', `age` int(3) DEFAULT NULL COMMENT '年龄', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `last_update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户测试表'; insert into t_user (name, age) values('小明',12); insert into t_user (name, age) values('小李',13); insert into t_user (name, age) values('小王',14);
READ-UNCOMMITTED 测试
A端操作 | B端操作 |
---|---|
set session tx_isolation = 'READ-UNCOMMITTED'; | - |
select * from t_users | - |
查询3条数据 | |
begin; | |
insert into t_user(name,age) values('小花', 10); | |
select * from t_users | - |
查询4条数据 | - |
- | rollback; |
select * from t_users | - |
查询3条数据 | - |
READ COMMITTED 测试
A端操作 | B端操作 |
---|---|
set session tx_isolation = 'READ-COMMITTED'; | - |
select * from t_users | - |
查询3条数据 | - |
- | begin; |
- | insert into t_user(name,age) values('小花', 10); |
select * from t_users | - |
查询3条数据 | - |
- | commit; |
select * from t_users | - |
查询4条数据 |
REPEATABLE READ 测试
经过前面2个测试,目前已经包含4条数据A端操作 | B端操作 |
---|---|
set session tx_isolation = 'REPEATABLE-READ'; | |
begin; | - |
select * from t_users; | - |
查询4条数据 | - |
- | begin; |
- | insert into t_user(name,age) values('小小', 6); |
select * from t_users; | - |
查询4条数据(【未发生脏读】) | - |
- | commit; |
select * from t_users; | |
查询4条数据(【可重复读】) | |
commit; | |
select * from t_users | - |
查询5条数据 | - |
REPEATABLE READ 可能引起幻影读的情况 MySQL 5.6 暂未出现
按照维基百科上的描述:
在可重复读(REPEATABLE READS)隔离级别中,基于锁机制并发控制的DBMS需要对选定对象的读锁(read locks)和写锁(write locks)一直保持到事务结束,但不要求“范围锁”,因此可能会发生“幻影读”。
当事务没有获取范围锁的情况下执行SELECT ... WHERE操作可能会发生“幻影读”。
“幻影读”是不可重复读的一种特殊场景:当事务1两次执行SELECT ... WHERE检索一定范围内数据的操作中间,事务2在这个表中创建了(如INSERT)了一行新数据,这条新数据正好满足事务1的“WHERE”子句
但我通过范围锁测试,并未出现幻读现象。
具体测试如下:
经过前面测试,目前已经包含5条数据
A端操作 | B端操作 |
---|---|
set session tx_isolation = 'REPEATABLE-READ'; | |
begin; | - |
select * from t_user where age between 10 and 20; | - |
查询4条数据(10~20共4条) | - |
- | begin; |
- | insert into t_user(name,age) values('小六', 20); |
- | commit; |
select * from t_user where age between 10 and 20; | |
查询4条数据(10~20共4条【未发生幻读】) | |
commit; | |
select * from t_users | - |
查询6条数据 | - |
Serializable 测试
经过前面测试,目前已经包含6条数据A端操作 | B端操作 |
---|---|
set session tx_isolation = 'SERIALIZABLE'; | |
begin; | - |
select * from t_user; | - |
查询5条数据 | - |
- | begin; insert into t_user(name,age) values('小七', 20); |
一直处于等待状态【串行化执行】 | |
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 【串行化执行】 | |
insert into t_user(name,age) values('小七', 20); | |
commit; | |
插入成功 | |
select * from t_users | - |
查询6条数据【未发生脏读】【可重复读】 | - |
commit; | |
select * from t_users | - |
查询7条数据 | - |
参考:
/detail/2669567300.html
https://www.jianshu.com/p/249f2cd42692
相关文章推荐
- Mysql加锁过程详解(6)-数据库隔离级别(2)-通过例子理解事务的4种隔离级别
- Spring事务配置及事务的传播性与隔离级别详解
- Spring事务配置及事务的传播性与隔离级别详解
- MySQL事务隔离级别详解
- MySQL之DML,事务及隔离级别详解
- Mysql加锁过程详解(6)-数据库隔离级别(2)-通过例子理解事务的4种隔离级别
- Spring事务配置及事务的传播性与隔离级别详解
- MySQL事务及隔离级别详解
- 事务的隔离级别详解
- Spring事务配置及事务的传播性与隔离级别详解
- 事务的隔离级别详解
- [数据库事务与锁]详解三: 深入分析事务的隔离级别
- 数据库事务隔离级别详解
- mysql的事务处理以及隔离级别详解
- 事务ACID特性及4种隔离级别详解
- 事务性质以及隔离级别
- 数据库并发机制和事务的隔离级别详解
- Mysql数据库事务的隔离级别和锁的实现原理分析(mvcc详解)
- 数据库事务隔离级别详解
- 数据库并发机制和事务的隔离级别详解