DM8事务管理,多版本并发控制,及达梦开发接口

事务管理,多版本并发控制,及达梦开发接口

文章目录

大家想学习达梦数据库或者解决报错问题,可以去达梦数据库社区https://eco.dameng.com

参考文章管理事务 | 达梦技术文档

一、事务管理

使用事务来管理 DM 数据库,对于 DM 数据库来说,第一次执行 SQL 语句时,隐式地启动一个事务,以COMMITROLLBACK 语句/方法显式地结束事务。

为了提高事务管理的灵活性,DM 数据库还提供了设置保存点(SAVEPOINT)和回滚到保存点的功能。保存点提供了一种灵活的回滚,事务在执行中可以回滚到某个保存点,在该保存点以前的操作有效,而以后的操作被回滚掉。

事务组提交

事务组提交(GROUP COMMIT)是一种数据优化策略,它允许数据库在一次磁盘操作中提交多个事务,而不是为每一个事务单独执行一次磁盘 I/O 操作。

COMMIT_WRITE=IMMEDIATE,WAIT 时,事务提交动作响应用户之前要求事务修改产生的 REDO 日志写入联机日志文件。在高并发的短事务提交场景会频繁触发 REDO 日志写入动作,高频向联机日志文件写入较小数据量的 REDO 日志,影响系统整体性能。

DM 可通过 INI 参数 COMMIT_BATCH 控制是否开启事务组提交以及触发一次写盘动作提交的事务数。一个事务提交不会马上触发 REDO 日志写盘动作,而是等待其他事务提交后合并写入。

二、事务锁定

2.1 锁的类型

DM 数据库支持多用户并发访问、修改数据,有可能出现多个事务同时访问、修改相同数据的情况。封锁机制是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据库对象进行操作前,需要先对其封锁。封锁后事务就对该数据库对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据库对象进行相应操作

DM 数据库使用四种不同的锁模式:共享锁、排他锁、意向共享锁和意向排他锁。

共享锁

共享锁(Share Lock,简称 S 锁)用于读操作,防止其他事务修改正在访问的对象。这种封锁模式允许多个事务同时并发读取相同的资源,但是不允许任何事务修改这个资源。

排他锁

排他锁(Exclusive Lock,简称 X 锁)用于写操作,以独占的方式访问对象,不允许任何其他事务访问被封锁对象;防止多个事务同时修改相同的数据,避免引发数据错误;防止访问一个正在被修改的对象,避免引发数据不一致。一般在修改对象定义时使用。

意向锁

意向锁(Intent Lock)用于读取或修改被访问对象数据时使用,多个事务可以同时对相同对象上意向锁,DM 支持两种意向锁:

  1. 意向共享锁(Intent Share Lock,简称 IS 锁):一般在只读访问对象时使用;
  2. 意向排他锁(Intent Exclusive Lock,简称 IX 锁):一般在修改对象数据时使用。

四种锁模式的相容矩阵如下表所示:

其中"Y"表示相容;"N"表示不相容。如表中第二行第二列为"Y",表示如果某个事务已经加了 IS 锁时,其他事务还可以继续添加 IS 锁,第二行第五列为"N",表示如果某个事务已经加了 IS 锁时,其他事务不能添加 X 锁。

PostgreSQL数据库中,锁的划分

2.2 锁的粒度

按照封锁对象的不同,锁可以分为 TID 锁和对象锁。

TID 锁

TID 锁以事务号为封锁对象,为每个活动事务生成一把 TID 锁,代替了其他数据库行锁的功能,防止多个事务同时修改同一行记录。

DM 实现的是行级多版本,每一行记录隐含一个 TID 字段,用于事务可见性判断。

只有多个事务同时修改同一行记录时,才会产生新的 TID 锁。例如,当事务 T1(事务号为 TID1)试图修改某行数据,而该行数据正在被另一个事务 T2(事务号为 TID2)修改(是通过数据多版本可见性来判断的),此时事务 T1 会生成一个新的 TID 锁,其锁对象为事务号 TID2,而非事务 T2。

同时多版本写不阻塞读的特性,SELECT 操作已经消除了行锁,因此 DM 中不再有行锁的概念。

对象锁

对象锁是 DM 新引入的一种锁,通过统一的对象 ID 进行封锁,确保对同一个对象的 DDL 操作是串行执行的。

防止多个事务同时采用批量方式插入、更新一张表,防止向正在使用 FAST LOADER 工具装载数据的表中插入数据等

此外,表锁还有一个作用,避免对存在未提交修改的表执行 ALTER TABLE、TRUNCATE TABLE 操作。

对象锁的封锁动作分为四类:

a) 独占访问(EXCLUSIVE ACCESS),不允许其他事务修改对象,不允许其他事务访问对象,使用 X 方式封锁

b) 独占修改(EXCLUSIVE MODIFY),不允许其他事务修改对象,允许其他事务共享访问对象,使用 S + IX 方式封锁

c) 共享修改(SHARE MODIFY),允许其他事务共享修改对象,允许其他事务共享访问对象,使用 IX 方式封锁

d) 共享访问(SHARE ACCESS),允许其他事务共享修改对象,允许其他事务共享访问对象,使用 IS 方式封锁

查看锁信息

sql 复制代码
SELECT ADDR,LTYPE,LMODE FROM V$LOCK;

三、多版本

在多版本控制以前,数据库对读操作上共享锁,写操作上排他锁,这种锁机制虽然解决了并发问题,但影响了并发性。

例如,当对一个事务对表进行查询时,另一个对表更新的事务就必须等待

DM 数据库的多版本,查询永远不会被阻塞也不需要上行锁,并通过 TID 锁机制消除了插入、删除、更新操作的行锁。数据库的读操作与写操作不会相互阻塞。

3.1物理记录格式

为了适应多版本机制,高效地获取历史记录,每一条物理记录中包含了两个字段:TID 和 RPTR。TID 保存修改记录的事务号,RPTR 保存回滚段中上一个版本回滚记录的物理地址。插入、删除和更新物理记录时,RPTR 指向操作生成的回滚记录的物理地址。物理记录格式如下:

物理记录 TID RPTR

新物理记录的RPTR指向当前回滚记录的物理地址。

3.2 回滚记录格式

回滚记录与物理记录一样,增加了两个字段:TID 和 RPTR。TID 保存回滚记录对应的事务号,RPTR 保存回滚段中上一个版本回滚记录的物理地址。

回滚记录 TID RPTR

插入物理记录时,由于没有更老的版本数据,回滚记录的 RPTR 值为 NULL;更新和删除物理记录时,RPTR 指向原始物理记录的 RPTR。

3.3可见性原则

实现多版本控制的关键是可见性判断,找到对当前事务可见的特定版本数据。DM 通过活动事务表,确定事务的可见性。根据事务隔离级的不同,在事务启动时(串行化),或者语句执行时(读提交),收集这一时刻所有活动事务,并记录系统中即将产生的事务号 NEXT_TID。DM 多版本可见性原则:

  1. 物理记录的 TRXID 等于当前事务号,说明是本事务修改的物理记录,物理记录可见;
  2. 物理记录的 TRXID 不在活动事务表中,并且 TRXID 小于 NEXT_TID,物理记录可见;
  3. 物理记录的 TRXID 包含在活动事务表中,或者 TRXID 大于等于 NEXT_TID,物理记录不可见。

3.4 历史数据获取

当物理记录对当前事务不可见时,根据物理记录和回滚记录的 RPTR 指针,向前回溯一个历史版本记录,通过此历史版本记录的 TID 字段,依据事务可见性原则判断此版本的记录对当前事务是否可见。

如不可见则根据 RPTR 指针继续向前回溯。

如果不及时清理回滚段,可能造成回滚段空间的不断膨胀,占用大量磁盘空间。DM 提供了自动清理、回收回滚段空间的机制。系统定时(缺省是每间隔 1 秒)扫描回滚段,根据回滚记录的 TID,判断是否需要保留回滚记录。

四、JDBC介绍

JDBC(Java Database Connectivity)是 Java 应用程序与数据库的接口规范,旨在让各数据库开发商为 Java 程序员提供标准的数据库应用程序编程接口(API)。JDBC 定义了一个跨数据库、跨平台的通用 SQL 数据库 API。

通过 JDBC 驱动程序,用户可以在应用程序中实现对 DM 数据库的连接与访问,JDBC 驱动程序的主要功能包括:

  1. 建立与 DM 数据库的连接;
  2. 转接发送 SQL 语句到数据库;
  3. 处理并返回语句执行结果。

五、ODBC介绍

ODBC 提供访问不同类型的数据库的途径。结构化查询语言 SQL 是一种用来访问数据库的语言。通过使用 ODBC,应用程序能够使用相同的源代码和各种各样的数据库交互。这使得开发者不需要以特殊的数据库管理系统 DBMS 为目标,或者了解不同支撑背景的数据库的详细细节,就能够开发和发布客户/服务器应用程序。

DM ODBC 3.0 遵照 Microsoft ODBC3.0 规范设计与开发,实现了 ODBC 应用程序与 DM 的互连接口。用户可以直接调用 DM ODBC 3.0 接口函数访问 DM,也可以使用可视化编程工具如 C++ Builder、PowerBuilder 等利用 DM ODBC 3.0 访问 DM。

DMODBC 在 Linux 操作系统上的使用依赖于 UnixODBC 库,如果 UnixODBC 未安装在系统目录下,则为了能使 DMODBC 能找到需要的库文件,用户需要设置系统环境变量 LD_LIBRARY_PATH 指向动态库。另外,如果安装的 UnixODBC 生成的动态库名称不是 libodbcinst.so(如 libodbcinst.so.1.0.0 或者 libodbcinst.so.2.0.0 等),则需要对实际库文件建立符号链接。

置系统环境变量 LD_LIBRARY_PATH 指向动态库。另外,如果安装的 UnixODBC 生成的动态库名称不是 libodbcinst.so(如 libodbcinst.so.1.0.0 或者 libodbcinst.so.2.0.0 等),则需要对实际库文件建立符号链接。

相关推荐
城数派1 小时前
省市县三级的逐年植被覆盖度(FVC)数据
数据库·arcgis·信息可视化·数据分析
2301_769340671 小时前
HTML函数运行时触控屏失灵是硬件故障吗_输入层兼容性测试【详解】
jvm·数据库·python
lifewange2 小时前
SQL Server介绍
数据库
Rubin智造社3 小时前
Claude Code开发者大会系列2|“饮鸩止渴”还是“即刻解药”?Anthropic与SpaceX的联姻内幕
大数据·数据库·人工智能·开发者大会·anthropic·claude code
噢,我明白了3 小时前
表单的完整 CRUD 练习【极简个人记账本】(含前端后端链接mySQL)
java·前端·数据库·mysql
2301_809204705 小时前
bootstrap怎么实现鼠标悬停切换图片预览功能
jvm·数据库·python
小短腿的代码世界10 小时前
Qt 股票订单撮合引擎:高频交易系统的核心心脏
开发语言·数据库·qt·系统架构·交互
JosieBook10 小时前
【数据库】时序数据库选型指南:从数据模型到大模型智能分析
数据库·时序数据库
小猿姐11 小时前
Clickhouse Kubernetes Operator 实测:哪种方案更适合生产?
运维·数据库·kubernetes