达梦数据库事务管理
事务定义
事务是指作为单个逻辑工作单元的一系列操作集合。一个典型的事务由一组操作序列组成。对于 DM 数据库,第一次执行 SQL 语句时会隐式启动一个事务,并在 COMMIT 或 ROLLBACK 语句/方法显式结束事务。此外,执行 DDL 前,DM 数据库会自动提交前面的操作,使其作为一个完整的事务结束。DDL 语句的事务处理受DDL_AUTO_COMMIT
参数控制。
查看和修改 DDL_AUTO_COMMIT
参数
SELECT PARA_NAME, PARA_VALUE, PARA_TYPE, DESCRIPTION
FROM v$dm_ini
WHERE para_name='DDL_AUTO_COMMIT';
事务操作
提交事务(COMMIT)
- 将事务的所有更新持久化到数据库中。
- 释放事务占用的资源(如锁)。
- 返回提交成功消息。
回滚事务(ROLLBACK)
- 撤销事务的所有更新,恢复到事务开始前的状态。
保存点(SAVEPOINT)
- 创建保存点:
SAVEPOINT sp_name;
- 回滚到保存点:
ROLLBACK TO SAVEPOINT sp_name;
事务特性
- 原子性:事务的操作要么全做,要么全不做。
- 一致性:事务将数据库从一个一致状态转换到另一个一致状态。
- 隔离性:事务的操作彼此隔离,不会相互干扰。
- 持久性:事务一旦提交,对数据库的改变是永久的。
事务模式
- 自动提交模式:
- 默认模式,所有操作自动提交。
- 设置自动提交:
SET AUTOCOMMIT ON;
- 手动提交模式:
- 需要显式提交(COMMIT)或回滚(ROLLBACK)。
- 隐式提交模式:
-
DDL 语句会自动提交前面的事务。
-- 创建保存点 SAVEPOINT sp_01; INSERT INTO DMHR.TEST01 VALUES(2, 'test_sp01'); -- 创建第二个保存点 SAVEPOINT sp_02; INSERT INTO DMHR.TEST01 VALUES(3, 'test_sp02'); -- 创建第三个保存点 SAVEPOINT sp_03; INSERT INTO DMHR.TEST01 VALUES(4, 'test_sp03'); -- 回滚到第二个保存点 ROLLBACK TO SAVEPOINT sp_02; INSERT INTO DMHR.TEST01 VALUES(3, 'test_sp02'); COMMIT;
-
回滚形式
- 自动回滚:
- 事务运行期间若连接断开,DM 数据库自动回滚该事务。
- 系统恢复时,未提交的事务会被自动回滚。
- 手动回滚:
- 回滚到保存点,保留保存点之前的操作,撤销之后的操作。
- 保存点示例:
达梦数据库的锁控制
锁是一种防止数据相互破坏的机制。它在维护数据库并发性和一致性方面起着至关重要的作用。当多个事务同时访问或修改相同的数据时,如果没有锁机制,可能会导致数据不一致和错误。
达梦(DM)数据库支持多用户并发访问和修改数据。在并发操作中,可能会出现多个事务同时访问或修改相同数据的情况。如果不加以控制,可能会访问到不正确的数据,破坏数据的一致性。
封锁机制是实现数据库并发控制的重要技术。当事务对某个数据库对象进行操作前,需要先对其封锁。在事务释放锁之前,其他事务不能对该对象进行相应操作。
锁模式
锁模式指定并发用户如何访问锁定资源。达梦数据库使用四种不同的锁模式:共享锁、排他锁、意向共享锁和意向排他锁。
1. 共享锁(Share Lock,S 锁)
- 用于:读操作
- 作用:防止其他事务修改正在访问的对象
- 特性:允许多个事务同时并发读取相同的资源,但不允许任何事务修改该资源
语句级回滚
- SQL 语句执行错误时,该语句的操作会被回滚,但不影响之前的操作。
ROLL_ON_ERR
参数控制语句级回滚:
SELECT PARA_NAME, PARA_VALUE, PARA_TYPE, DESCRIPTION
FROM v$dm_ini
WHERE para_name='ROLL_ON_ERR';
2. 排他锁(Exclusive Lock,X 锁)
- 用于:写操作
- 作用:以独占方式访问对象,防止其他事务访问被封锁的对象
- 特性:不允许多个事务同时修改相同的数据,防止数据错误和数据不一致
3. 意向锁(Intent Lock)
意向锁用于读取或修改被访问对象的数据,多个事务可以同时对相同对象上意向锁。达梦数据库支持两种意向锁:
- 意向共享锁(Intent Share Lock,IS 锁)
- 用于:只读访问对象
- 特性:表明事务即将在行级别获取共享锁(S 锁),多个事务可以同时获取 IS 锁
- 意向排他锁(Intent Exclusive Lock,IX 锁)
- 用于:修改对象数据
- 特性:表明事务即将在行级别获取排他锁(X 锁),多个事务可以同时获取 IX 锁
锁模式的相容矩阵
下表显示了四种锁模式之间的相容性,其中“Y”表示相容,“N”表示不相容:
IS | IX | S | SIX | X | |
---|---|---|---|---|---|
IS | Y | Y | Y | N | N |
IX | Y | Y | N | N | N |
S | Y | N | Y | N | N |
SIX | N | N | N | N | N |
X | N | N | N | N | N |
- 如果某个事务已经加了 IS 锁,其他事务可以继续添加 IS 锁,但不能添加 X 锁。
- 如果某个事务已经加了 IX 锁,其他事务可以继续添加 IS 锁和 IX 锁,但不能添加 S 锁或 X 锁。
总结
- 共享锁(S 锁):用于读操作,防止数据修改。
- 排他锁(X 锁):用于写操作,以独占方式访问对象。
- 意向锁(IS 锁和 IX 锁):用于标明事务在行级别的锁意图,支持并发读写操作。
通过这些锁模式和相容矩阵,达梦数据库能够有效管理并发操作,确保数据一致性和系统性能。
达梦数据库的锁可以按照封锁对象的不同,分为 TID 锁和对象锁。
1. TID 锁
概念:
- TID锁用于控制并发访问,以事务号(TID)作为锁对象。
- 每个活动事务生成一个唯一的TID锁,用于防止多个事务同时修改同一行记录。
- 与其他数据库的行锁不同,TID锁代替了行锁的功能。
工作机制:
- 当事务T1修改一行数据时,会将其事务号(TID1)写入该行数据的TID字段,隐式地加上TID锁。
- 事务T2尝试修改同一行数据时,发现该行数据的TID字段已被TID1占用,T2会等待T1完成修改并释放锁。
优点:
- 避免大量行锁对系统资源的消耗。
- 在执行INSERT、DELETE、UPDATE操作时,不需要额外的行锁,通过设置事务号到TID字段来隐式地加锁。
- 只有在多个事务同时修改同一行记录时,才会产生新的TID锁。
多版本并发控制(MVCC):
- 每行记录隐含一个TID字段,用于事务可见性判断。
- SELECT操作不再需要行锁,读操作不会被写操作阻塞。
2. 对象锁
概念:
- 对象锁通过统一的对象ID进行封锁。
- 将对数据字典的封锁和表锁合并为对象锁,以减少封锁冲突,提升系统并发性能。
优点:
- 通过统一管理对象ID,减少锁冲突。
- 提高系统的并发性能。
对象锁的应用场景: - 数据字典操作:如修改表结构。 - 表级别操作:如表级别的锁定。
归纳总结
- TID 锁:
- 以事务号(TID)为锁对象,防止多个事务同时修改同一行记录。
- 代替行锁,减少系统资源消耗。
- 结合MVCC机制,读操作不被写操作阻塞。
- 对象锁:
- 通过统一的对象ID进行封锁,减少封锁冲突。
- 将数据字典锁和表锁合并,提升系统并发性能。
通过这两种锁机制,达梦数据库能够有效管理并发操作,确保数据的一致性和系统性能。