南大通用GBase 8s 数据库封锁与并发事务调度介绍

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 南大通用GBase 8s 数据库封锁与并发事务调度介绍

本文探讨GBase 8s的事务处理特性,揭示它是如何确保ACID特性,并有效管理并发事务的。

事务的概念
将用户在数据库中的某些操作集合看作一个整体,在其有序执行的过程中不被其他操作影响,这样的操作集合就是事务。
事务(Transaction)是对数据库进行操作的集合。该集合是一个不可分割的具有逻辑功能的工作单元,集合中的操作在事务的一次执行中必须全部被执行或者全部。
事务的特性(ACID 特性)
Atomicity: 原子性,构成该事务的操作集合中的全部操作在事务的运行过程中全部执行或者全部不执行。
Consistency: 一致性,事务运行的结果应该使数据库保持数据一致性。
Isolation:隔离性,构成某个事务的全部操作与其他事务或操作是隔离的,同时执行的事务之间不能够互相影响,一个事务单独运行的结果应该与该事务和其他多个事务同时运行的结果一致。
Durability: 持久性,事务的持久性是指事务运行完毕并成功提交后,其对数据库全部操作的结果应该永久地保留在数据库中。
并发事务的调度
1、并发问题和并发操作
实际应用中,通常会有来自不同用户的多个事务并发执行,事务之间会有交叉,这个问题就是事务的并发问题。
并发事务之间相互影响,会破坏相关事务的正常运行,无法保证事务的 ACID 特性,产生数据错误。
并发操作(Simultaneous Concurrency)对于数据库的并发操作是由并发运行的多个事务引起的,是并发事务中包含的对数据库的操作。
并发操作是由多个事务并发进行而产生的,其最大问题是容易导致数据库的不一致性
举例说明

两个售票点同时售出同一天同一车次的车票,第一个售票点执行的数据库事务 T1 为:

(1)读出当前车票的剩余数量 A,假设 A=50;

(2)售出一张票,剩余数量变为 A=A-1,即 A=49。

第二个售票点执行的数据库事务 T2 为:

(1)读出当前车票的剩余数量 A,假设 A=50;

(2)售出一张票,剩余数量变为 A=A-1,即 A=49。

事务 T1 和 T2 按照如下顺序并发执行:

(1)读出当前车票的剩余数量 A,假设 A=50;

(2)读出当前车票的剩余数量 A,假设 A=50;

(3)售出一张票,剩余数量变为 A=A-1,即 A=49;

(4)售出一张票,剩余数量变为 A=A-1,即 A=49。

事务执行的结果是只卖了一张车票,而实际上售出了两张,这样就可能导致同一个座位售出两张车票,数据库出现了数据的不一致性错误。

并发操作导致数据库出现数据不一致性的问题,如下表所示。事务 T1 将数据对象,即火车票的总数 A 进行了修改,变为 49,而事务 T2 在 T1 修改 A 之前读取的 A 的值仍然

是 50,T2 将此值修改为 49 后写回数据库并覆盖了 T1 事务对 A 的修改,此时,A 的值为49,就会出现这种情况:卖出两张车票后车票总数应为 48,而数据库中车票的总数为 49,

显然出现了数据的不一致性错误。

2、调度
调度(Schedule)是指事务的执行次序。
如果多个事务依次执行,则称为事务的串行调度(Serial Schedule)。
如果多个事务同时执行,则称为事务的并发调度(Concurrent Schedule)
3、冲突
冲突(conflict):事务调度中的两个操作(读操作或写操作),如果交换顺序执行,它们所属的事务运行结果会改变,那么这两个操作就被称为冲突。
不同事务对于不同数据对象进行操作(无论是读操作还是写操作)不会产生冲突;不同事务对同一数据对象进行读操作也不会产生冲突。
4、封锁
并发控制的主要技术是封锁(Locking)
封锁的对象是数据库中的数据对象,如关系型数据库中的表、记录、属性、索引等
对数据对象加锁的时机是在事务对其进行操作之前,向系统发出加锁请求。
加锁后事务 T就取得了对该数据对象的控制,在事务 T 释放它的锁之前,其他事务不能对此数据对象进行任何操作。
封锁是一种排队机制,将并行任务按锁的先后顺序排队,把并行任务变成串行任务。
5、封锁产生的问题
封锁技术在一定程度上解决了数据库的并发事务处理过程中,并发操作给数据库带来的数据一致性问题,但同时产生了新的问题如活锁和死锁。

活锁问题
在处理并发事务的过程中,如果事务 T1 在数据对象 R 上加锁,事务 T2 又请求为数据 对象 R 加锁,则 T2 必须等待 T1 释放加在 R 上的锁。如果事务 T3 也请求为 R 加锁,当 T1 释放了 R 上的锁之后系统首先响应 T3 的请求,则允许 T3 对 R 加锁,此时 T2 仍需等 待 T3 释放加在 R 上的锁。然后事务 T4 又请求封锁 R,当 T3 释放了 R 上的封锁之后系统 又响应了 T4 的请求……T2 有可能永远等待而无法为 R 加锁,这就是活锁。

活锁也称饿死,由于事务永远得不到封锁而导致。避免活锁可以采用先来先服务的策略。当多个事务请求封锁同一个数据对象时,可按照请求封锁的先后次序对事务排队,数据对象上的锁一旦释放就批准申请队列的第一个事务获得封锁。 

T1

T2

T3

T4

LOCK (R)

……

……

UNLOCK (R)

LOCK (R)

等待

等待

等待

等待

LOCK (R)

等待

LOCK (R)

……

UNLOCK (R)

LOCK (R)

等待

等待

等待

LOCK (R)

……

死锁问题
如果事务 T1 对数据对象 R1 进行封锁,T2 对数据对象 R2 进行封锁,然后 T1 又请求对 R2 进行封锁,由于 T2 已封锁了 R2,则 T1 必须等待 T2 释放 R2 上的锁。接着 T2 又申请对 R1 进行封锁,由于 T1 已封锁 R1,因此,T2 也只能等待 T1 释放 R1 上的锁。这样就出现了事务 T1 等待另一个事务 T2 释放相关数据对象上的锁,而 T2 又在等待 T1 释放相关对象上的锁,T1 和 T2 两个事务由于相互等待对方释放数据对象上的锁而永远不能继续执行,这样就出现了死锁。

死锁(Dead Lock):系统中有两个或两个以上的事务都处于等待状态,并且每个事务都在等待其中另一个事务释放封锁,这样才能继续执行下去,结果造成任何一个事务都无法继续执行,这种现象称数据库系统进入了“死锁”(Dead Lock)状态

用例简单复现死锁产生

GBase模式下(会话1):

Create database if not exists testdb with buffered log;
Database testdb;
Create table if not exists a(c1 int,c2 int);
Create table if not exists b(c1 int,c2 int);
Insert into a values(1,1);
Insert into a values(2,2);
Insert into b values(1,1);
Insert into b values(1,1);
!sh /tmp/rd129/onmode_I143_rd129
Set isolation to repeatable read;
Set lock mode to wait;
Begin;
Select *from b;                   --读b表,对b表加上S锁
!echo “sql start sleep 5!sleep 15
!echo “sql sleep 5 done”
Update a set c1=6 where c2=2;     -更新a表,想对a表加上X锁
Commit;
Close database;
!cat /tmp/rd129/out.log
Drop database testdb;

onmode_I143_rd129内容如下(会话2):
Onmode -I 143
(
Dbaccess -e-m testdb - <<!
Set isolation to repeatable read;
Set lock mode to wait;
Begin;
Select * from a;                 --读a表,对a表加上S锁
!echo “sql start sleep 5!sleep 10
!echo “sql sleep 5 done”
Update b set c1=6 where c2=2;   --更新b表,想对b表加上X锁
Commit;
!
) >/tmp/rd129/out.log 2>&1 &

那么两个会话分别在同一个库中,对a表和b表加上共享锁S,当想进行更新时,会话1在等待会话2释放a的S锁,而会话2在等待会话1释放b的S锁,从而导致死锁产生。

那么在oracle模式下,该用例却不能产生死锁。

因为在GBase模式下,开启事务后,可以保证两个会话在执行更新后才提交保证两个会话同时进行。

而在oracle模式下,只能开启多语句模式,DML语句会自动开启事务,通过commit/rollback结束事务,DDL会提交事务。从而导致两个会话可能无法同时进行,因此并行变成串行,导致死锁无法产生。

南大通用GBase 8s数据库的事务处理能力和并发控制机制,为企业提供了一个可靠、高效和安全的数据处理平台。无论是金融交易还是在线事务处理,GBase 8s都能确保数据的完整性和一致性,满足企业对数据库系统的要求。

相关文章
|
3天前
|
存储 数据库
快速搭建南大通用GBase 8s数据库SSC共享存储集群
本文介绍如何GBase8s 数据库 在单机环境中快速部署SSC共享存储集群,涵盖准备工作、安装数据库、创建环境变量文件、准备数据存储目录、修改sqlhost、设置onconfig、搭建sds集群及集群检查等步骤,助你轻松完成集群功能验证。
|
3天前
|
存储 缓存 网络安全
南大通用GBase 8s 数据库 RHAC集群基本原理和搭建步骤
南大通用GBase 8s 数据库 RHAC集群基本原理和搭建步骤
|
1天前
|
存储 机器学习/深度学习 监控
南大通用GBase 8s数据库onbar基础使用教程
数据备份与恢复是确保数据安全和业务连续性的关键。onbar作为GBase 8s数据库的备份工具,需配合存储管理器使用,通过配置BAR_BSALIB_PATH等参数,实现数据的备份与恢复。本文详细介绍了onbar的配置、备份、恢复及监控流程,帮助数据库管理员构建高效的数据保护方案。
|
SQL Oracle 关系型数据库
国产化人大金仓数据库转库工具:oracle12c数据库转kingbase8.6人大金仓数据库实例演示
国产化人大金仓数据库转库工具:oracle12c数据库转kingbase8.6人大金仓数据库实例演示
1015 0
国产化人大金仓数据库转库工具:oracle12c数据库转kingbase8.6人大金仓数据库实例演示
|
3月前
|
XML 分布式数据库 数据库
【计算机三级数据库技术】第13章 大规模数据库架构--附思维导图
文章概述了分布式数据库、并行数据库、云计算数据库架构和XML数据库的基本概念、目标、体系结构以及与传统数据库的比较,旨在提供对这些数据库技术的全面理解。
44 1
|
SQL Kubernetes 安全
国产数据库-技术特性-CloudberryDB
Cloudberrydb基于gpdb,支持PG14内核,有很多GP目前不支持的优秀特性
450 0
|
SQL 存储 Kubernetes
「列式数据库」与其他数据库相比较,YugabyteDB太强了
「列式数据库」与其他数据库相比较,YugabyteDB太强了
|
存储 Cloud Native 多模数据库
阿里云数据库Lindorm刷新TPC物联网测试纪录:性能比第二名高40%
国际处理性能委员会TPC官方披露,在该机构组织的衡量物联网网关系统性能的基准测试中,阿里自研云原生多模数据库Lindorm性能指标创下新纪录,达到485万IoTps,比第二名高出40%,同时成本降低60%以上。
3588 0
阿里云数据库Lindorm刷新TPC物联网测试纪录:性能比第二名高40%
Uma
|
Oracle 关系型数据库 分布式数据库
DTCC 2019 | 深度解码阿里数据库实现 数据库内核——基于HLC的分布式事务实现深度剖析
摘要:分布式事务是分布式数据库最难攻克的技术之一,分布式事务为分布式数据库提供一致性数据访问的支持,保证全局读写原子性和隔离性,提供一体化分布式数据库的用户体验。本文主要分享分布式数据库中的时钟解决方案及分布式事务管理技术方案。
Uma
8225 0
下一篇
无影云桌面