达梦数据库事务隔离级别介绍

本文详细介绍了数据库事务的ACID特性,重点关注隔离性,并通过实例解释了脏读、不可重复读和幻读现象。SQL标准定义了四种事务隔离级别:未提交读、已提交读、可重复读和可串行化,分别对应解决这些问题的程度。此外,文章还对比了达梦、Oracle、Postgresql和Mysql的事务隔离级别设置,并提供了达梦数据库开启不同隔离级别的示例。

前言

我们知道数据库事务具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)四个特性,简称 ACID。那什么是隔离性呢?

概念说明

脏读

在一个事务中可以读到其他未提交的事务产生或变更的数据。

	-- 脏读测试 
	SQL> create table test_uncommitted(id int, info varchar);
	操作已执行
	SQL> insert into test_uncommitted values (1, 'test');
	影响行数 1
	SQL> commit;
	操作已执行
	SQL> SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
	操作已执行
	SQL> select * from test_uncommitted;
	行号     ID          INFO
	---------- ----------- ----
	1          1           test
	
	-- 其他会话更新这份数据, 但不提交.
	SQL> update test_uncommitted set info='new' where id=1;
	影响行数 1
	
	-- 脏读出现
	SQL> select * from test_uncommitted;
	行号     ID          INFO
	---------- ----------- ----
	1          1           new
不可重复读

不可重复读指的是在同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能会受到其他事务的影响,比如其他事务改了这批数据并提交了。通常指数据更新(UPDATE)操作。

	--	不可重复读测试
	SQL> create table test_unrepeatable(id int, info varchar);
	操作已执行
	SQL> insert into test_unrepeatable values (1, 'test');
	影响行数 1
	SQL> commit;
	操作已执行
	SQL> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
	操作已执行
	SQL> select * from test_unrepeatable where id=1;
	行号     ID          INFO
	---------- ----------- ----
	1          1           test

	-- 其他会话更新这份数据, 并提交.SQL> update test_unrepeatable set info='new' where id=1;
	影响行数 1
	SQL> commit;
	操作已执行
	
	-- 不可重复读出现.
	SQL> select * from test_unrepeatable where id=1;	
	行号     ID          INFO
	---------- ----------- ----
	1          1           new
幻读

在一个事务中, 再次执行同样的SQL, 得到的结果可能不一致。通常指数据插入(INSERT)操作。

	--  幻读测试
	SQL> create table test_phantom(id int, info varchar);
	操作已执行
	SQL> insert into test_phantom values (1, 'test');
	影响行数 1
	SQL> commit;
	操作已执行
	SQL> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
	操作已执行
	SQL> select * from test_phantom;
	行号     ID          INFO
	---------- ----------- ----
	1          1           test

 	-- 其他会话新增数据SQL> insert into test_phantom values (2, 'new');
	影响行数 1
	SQL> commit;
	操作已执行

	-- 幻读出现
	SQL> select * from test_phantom;
	行号     ID          INFO
	---------- ----------- ----
	1          1           test
	2          2           new

事务隔离级别

SQL 标准定义了四种隔离级别分别是:
  1. 未提交读 (READ UNCOMMITTED)
  2. 已读提交 (READ COMMITTED)
  3. 可重复读 (REPEATABLE READ)
  4. 可串行化 (SERIALIZABLE)

事务隔离其实就是为了解决上面提到的脏读、不可重复读、幻读这几个问题,下面展示了 4 种隔离级别对这三个问题的解决程度。

隔离级别 \ 解决脏读不可重复读幻读
未提交读可能可能可能
已提交读不可能可能可能
可重复读不可能不可能可能
可串行化不可能不可能不可能

注:对于可重复读能否解决幻读问题,只有Mysql的可重复读隔离级别在不加间隙锁(Next-Key锁)的情况下,才可能出现幻读。

达梦与其他数据库隔离级别对比

隔离级别 \ 数据库达梦OraclePostgresqlMysql(InnoDB)
未提交读支持不支持不支持支持
已提交读支持(默认)支持(默认)支持(默认)支持
可重复读支持支持支持支持(默认)
可串行化支持支持支持支持

达梦如何开启事务隔离级别

未提交读隔离级别

未提交读隔离级别是最不严格的隔离级别,在使用这个隔离级别时,会发生脏读、不可重复读和幻读。一般来说,未提交读隔离级别通常只用于访问只读表和只读视图,以消除可见性判断带来的系统开销,提升查询性能,该级别下事务为只读模式。

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
已提交读隔离级别(默认)

数据库的已提交读隔离级别可以确保只访问到已提交事务修改的数据,保证数据处于一致性状态。
默认就是已提交读隔离级别

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
可重复读隔离级别

在达梦数据库中可重复读隔离级别可以避免不可重复读和幻读问题,为了在并发环境下得到一个稳定结果,比如,财务对账中,我们可以设置可重复读事务隔离级别。可重复读相对于序列化在性能上能更灵活一些。

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
可串行化隔离级别

在要求消除不可重复读或幻读的情况下,我们可以设置事务隔离级为可串行化。跟已提交读隔离级别相比,可串行化事务的查询本身不会增加任何代价,但修改数据可能引发“串行化事务被打断”的错误。

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

注意

设置事务隔离级别必须在事务开启之前,事务开启后,再修改事务隔离级别将会报错:试图在事务运行中,改变其属性。

<think> 我们之前讨论了如何查看达梦数据库事务隔离级别,现在用户的问题是询问如何修改事务隔离级别。 根据达梦数据库的文档和常见操作,修改事务隔离级别主要有两种方法:系统级设置(全局)和会话级设置(当前会话)。 注意:达梦数据库事务隔离级别设置与SQL标准一致,包括读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和可串行化(SERIALIZABLE)。默认是读已提交。 方法1:修改系统级(全局)事务隔离级别 - 通过修改配置文件dm.ini中的参数ISOLATION_LEVEL,然后重启数据库实例生效。 - 或者,使用系统过程sp_set_para_value动态修改(部分版本支持动态修改,但修改后也需要重启)。 方法2:修改当前会话的事务隔离级别 - 在会话中使用SQL语句直接设置,语法为: SET TRANSACTION ISOLATION LEVEL <level>; 其中<level>可以是:READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE。 下面我将详细说明这两种方法。 步骤1:修改全局事务隔离级别(需要DBA权限) a. 通过修改dm.ini文件: - 找到数据库实例的dm.ini文件(通常在达梦数据库安装目录下的data文件夹中,以实例名命名的子文件夹内)。 - 找到参数ISOLATION_LEVEL,将其值改为对应的数字(0:读未提交,1:读已提交,2:可重复读,3:可串行化)。注意:达梦默认是1(读已提交)。 - 保存文件,并重启数据库服务。 b. 使用系统存储过程(动态修改,但需要重启): - 以SYSDBA用户登录数据库。 - 执行以下命令: SP_SET_PARA_VALUE(scope, 'ISOLATION_LEVEL', level_value); 其中: scope: 1表示内存和配置文件都修改(需要重启生效),2表示只修改内存(临时生效,重启后失效) level_value: 0,1,2,3(分别对应四种隔离级别) - 注意:即使使用scope=2临时修改内存,对已经存在的会话也不生效,只对新会话生效。而且修改全局参数通常需要重启。 步骤2:修改当前会话的事务隔离级别(不需要重启,立即生效) 在需要修改的会话中,执行SQL语句: SET TRANSACTION ISOLATION LEVEL <隔离级别名称>; 例如,设置为可重复读: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; 注意: - 这个设置只影响当前会话,不影响其他会话。 - 设置后,后续的事务都将使用这个隔离级别。 - 可以在事务开始前设置,事务中设置可能会报错(建议在事务开始前设置)。 补充说明: 达梦数据库还支持在事务开始时指定隔离级别(使用START TRANSACTION语句),例如: START TRANSACTION ISOLATION LEVEL REPEATABLE READ; 这样,该事务就会使用指定的隔离级别,而不影响其他事务。 重要提示: 修改全局隔离级别要谨慎,因为不同隔离级别对并发性能和一致性有不同影响。通常建议在应用开发时根据需要在会话级别调整。 下面生成相关问题。 </think> ### 达梦数据库修改事务隔离级别的方法 达梦数据库支持在**会话级**和**全局级**修改事务隔离级别,以下是具体操作方法: --- #### 一、会话级修改(立即生效,仅影响当前会话) 在SQL命令行或客户端工具中执行: ```sql SET TRANSACTION ISOLATION LEVEL <隔离级别名称>; ``` **可选级别**: - `READ UNCOMMITTED`(读未提交) - `READ COMMITTED`(读已提交,默认级别) - `REPEATABLE READ`(可重复读) - `SERIALIZABLE`(可串行化) **示例**: ```sql -- 设置为可重复读 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; ``` --- #### 二、全局级修改(需重启生效) ##### 方法1:通过配置文件修改 1. 在数据库配置文件 `dm.ini` 中添加或修改参数: ```ini ISOLATION_LEVEL = <数字代码> ``` **数字代码映射**: - 0:读未提交 - 1:读已提交(默认) - 2:可重复读 - 3:可串行化 2. 重启数据库实例使配置生效。 ##### 方法2:通过系统函数动态修改(需DBA权限) ```sql SP_SET_PARA_VALUE(scope, 'ISOLATION_LEVEL', level_value); ``` **参数说明**: - `scope`: - `1`:同时修改内存和配置文件(需重启生效) - `2`:仅修改内存(临时生效,重启后失效) - `level_value`:隔离级别数字代码(0-3) **示例**(永久设置为可串行化): ```sql SP_SET_PARA_VALUE(1, 'ISOLATION_LEVEL', 3); ``` --- #### 三、事务级临时修改(仅影响单次事务) 在事务开始时指定隔离级别: ```sql START TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- 后续SQL操作... COMMIT; ``` --- ### 注意事项 1. **权限要求**: - 会话级修改:用户需具备 `ALTER SESSION` 权限 - 全局修改:需 `DBA` 或 `SYSDBA` 权限 [^1][^2] 2. **生效范围**: - 会话级设置会覆盖全局设置 - 事务级设置会覆盖会话设置 3. **兼容性**: 达梦的隔离级别行为与SQL标准及Oracle高度兼容,但可重复读(`REPEATABLE READ`)实际通过**多版本并发控制(MVCC)** 实现,能避免不可重复读但可能允许幻读 [^3][^4]。 4. **验证方法**: 修改后可通过查询确认: ```sql SELECT isolation FROM V$TRX; -- 查看当前事务隔离级别 SELECT para_value FROM V$DM_INI WHERE para_name='ISOLATION_LEVEL'; -- 查看全局配置 ``` > ⚠️ **关键建议**:生产环境修改全局隔离级别前需充分测试,不同级别对并发性能和锁机制有显著影响 [^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值