本文共 2804 字,大约阅读时间需要 9 分钟。
在关系型数据库中,事务的隔离性分为四个隔离级别:读未提交、读提交、可重复读、串行化;DM 数据库支持三种事务隔离级别:读未提交、读提交和串行化。其中,读提交是 DM 数据库默认使用的事务隔离级别,可重复读升级为更严格的串行化隔离级。
由于数据库事务隔离级别的不同,在读取数据的时候会出现脏读、不可重复度、幻像读等不同的读数据现象。
1.1 脏读(DirtyRead) 所谓脏读就是对脏数据的读取,而脏数据所指的就是未提交的已修改数据。也就是说,一个事务正在对一条记录做修改,在这个事务完成并提交之前,这条数据是处于待定状态的(可能提交也可能回滚),这时,第二个事务来读取这条没有提交的数据,并据此做进一步的处理,就会产生未提交的数据依赖关系,这种现象被称为脏读。如果一个事务在提交操作结果之前,另一个事务可以看到该结果,就会发生脏读。 脏读在数据库事务隔离级别为读未提交的情况下会出现。在实际生产环境中,脏读是一定要避免的。1.2 不可重复读(Non-RepeatableRead)
一个事务先后读取同一条记录,但两次读取的数据不同,我们称之为不可重复读。如果一个事务在读取了一条记录后,另一个事务修改了这条记录并且提交了事务,再次读取记录时如果获取到的是修改后的数据,这就发生了不可重复读情况。 不可重复读在数据库事务隔离级别为读未提交和读提交的情况下出现。1.3 幻像读(PhantomRead)
一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为幻像读。 幻像读在数据库事务隔离级别为读未提交、读提交和可重复读的情况下会出现,而在DM中可重复读的数据库事务隔离级别升级为了更严格的串行化隔离级别,因此在DM中幻像读只会在数据库隔离级别为读未提交和读提交的情况下出现。DM 数据库支持三种事务隔离级别:读未提交、读提交和串行化。
2.1读未提交隔离级 读未提交隔离级别是最不严格的隔离级别。实际上,在使用这个隔离级别时,有可能发生脏读、不可重复读和幻像读。一般来说,读未提交隔离级别通常只用于访问只读表和只读视图,以消除可见性判断带来的系统开销,提升查询性能。 用户可以在事务开始时使用以下语句,设定事务为读未提交隔离级:SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
例:
在事务执行前设置事务的隔离级别为读未提交:新建一个查询会话窗口1,建表test_iso2并插入数据:set transaction isolation level read uncommitted;create table test_iso2( id int, name varchar(20));insert into test_iso2 values(1,'Tom');insert into test_iso2 values(2,'Nike');
新建一个查询会话窗口2,设置事务的隔离级别为读未提交,查询表test_iso2数据:
set transaction isolation level read uncommitted;select * from test_iso2;
可以查询到未提交数据:
2.2读提交隔离级 DM 数据库的读提交隔离可以确保只访问到已提交事务修改的数据,保证数据处于一致性状态,能够满足大多数应用的要求,并最大限度的保证系统并发性能,但可能会出现不可重复读取和幻像读。 用户可以在事务开始时使用以下语句设定事务为读提交隔离级:SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
例:
设置事务的隔离级别为读提交:set transaction isolation level read committed;
在会话窗口1建表test_iso并插入数据:
create table test_iso( id int, name varchar(20));insert into test_iso values(1,'Tom');insert into test_iso values(2,'Nike');
新开一个查询会话窗口2,查询表test_iso数据:
select * from test_iso;
不能查询到数据:
在会话窗口1中进行提交操作:commit;
在查询会话窗口2,查询表test_iso数据:
select * from test_iso;
可以查询到插入的数据:
2.3串行化隔离级 在要求消除不可重复读取或幻像读的情况下,我们可以设置事务隔离级为串行化。跟读提交隔离级相比,串行化事务的查询本身不会增加任何代价,但修改数据可能引发“串行化事务被打断”错误。 具体来说,当一个串行化事务试图更新或删除数据时,而这些数据在此事务开始后被其他事务修改并提交时,DM 数据库将报“串行化事务被打断”错误。 如果系统中存在长时间运行的写事务,并且该长事务所操作的数据还会被其他短事务频繁更新的话,最好避免使用串行化事务。 用户可以在事务开始时使用以下语句设定事务为串行化隔离级:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
例:
新建一个查询会话窗口6,在事务执行前设置事务的隔离级别为读可串行化,建表test_iso3并插入数据:set transaction isolation level serializable;create table test_iso3( id int, name varchar(20));insert into test_iso3 values(1,'Tom');insert into test_iso3 values(2,'Nike');
新建一个查询会话窗口7,设置事务的隔离级别为读可串行化,更新表test_iso3 中数据:
set transaction isolation level serializable;update test_iso3 set name='zhangsan' where id ='1';
会话6中的事务6进行提交
commit;
在会话7中执行查询表test_iso3 数据:
select * from test_iso3;
查询数据记录为空:
2.4只读事务 除了前面所述的各种标准特性外,DM 数据库还支持只读事务,只读事务只能访问数据,但不能修改数据。并且只读事务不会改变事务原有的隔离级。 用户可以在事务开始时使用以下语句,设定事务为只读事务:SET TRANSACTION READ ONLY;
转载地址:http://dlmen.baihongyu.com/