【数据库】数据库并发控制的目标,可串行化序列的分析,并发控制调度器模型
数据库并发控制
专栏内容:
- 手写数据库toadb
本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。
本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段学习。
开源贡献:
- toadb开源库
个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.
文章目录
- 数据库并发控制
- 前言
- 概述
- 并发调度器
- 可串行化
- 可串行化概念
- 案例分析
- 可串行化的模型
- 总结
- 结尾
前言
随着信息技术的飞速发展,数据已经渗透到各个领域,成为现代社会最重要的资产之一。在这个大数据时代,数据库理论在数据管理、存储和处理中发挥着至关重要的作用。然而,很多读者可能对数据库理论感到困惑,不知道如何选择合适的数据库,如何设计有效的数据库结构,以及如何处理和管理大量的数据。因此,本专栏旨在为读者提供一套全面、深入的数据库理论指南,帮助他们更好地理解和应用数据库技术。
数据库理论是研究如何有效地管理、存储和检索数据的学科。在现代信息化社会中,数据量呈指数级增长,如何高效地处理和管理这些数据成为一个重要的问题。同时,随着云计算、物联网、大数据等新兴技术的不断发展,数据库理论的重要性日益凸显。
因此,本专栏的分享希望可以提高大家对数据库理论的认识和理解,对于感兴趣的朋友带来帮助。
概述
数据库同一时间会运行很多的事务,有客户端发起的,也有数据库系统内部产生的,那么这事务的并发执行,相互之间的影响会导致数据库的状态不一致;
虽然每个事务的执行状态都是正确的,而且也没有发生故障和错误,但也没法确保数据正确。
这就需要数据库进行统一协调,让各个事务并发执行时,按照一定的规范来让它们有次序的执行,这就是数据库中的调度器需要做的事。
本文就来聊聊数据库的并发调度器的那些事。
并发调度器
数据库调度器让并发执行的事务,保持数据库状态一致的过程,就是并发控制。
当事务执行时,需要对数据库元素进行读写,这时就会向调度器请求,大多数情况下,调度器都会直接进行读写处理;如果数据库元素没有在缓冲区时,先向缓冲区管理器进行请求,让它加载到缓冲区中。
而在某些情况下,立即执行是不安全的,调度器会延迟这些请求,有些并发控制技术中,调度器甚至会拒绝,导至事务的中止。
可串行化
调度器如何判断执行的安全性,也就是并发执行事务保持数据库状态的一致性,在数据库中叫做可串行化;
当然还有另一种更强,更重要的条件,叫做冲突的可串行化,这是大多数数据库真正实现的调度器。
可串行化概念
当一个事务在隔离状态下执行时(即没有其它事务与它并发执行),将数据库从任何一个状态转换为另一个一致的状态;通常都会有其它事务与它并发,所以这种原则没法适用。
所以我们需要一种可串行化调度的策略,让并发事务可串行化调度执行的结果,与一次执行一个事务产生的结果相同,那么这个调度产生的执行动作的序列,就叫做可串行化的调度。
案例分析
假设有两个事务T1,T2,操作对角为数据A和数据B,初始值都是25;
每个事务在执行计算时,会先读出数据,再修改,然后写回;
- 事务执行序列为T1执行完,再执行T2
| 事务T1 | 事务T2 | 数据A | 数据B |
|---|---|---|---|
| 25 | 25 | ||
| read(A,t) | |||
| t = t + 100 | |||
| write(A,t) | 125 | ||
| read(B,t) | |||
| t = t + 100 | |||
| write(B,t) | 125 | ||
| read(A,t) | |||
| t = t*2 | |||
| write(A,t) | 250 | ||
| read(B,t) | |||
| t = t*2 | |||
| write(B,t) | 250 |
- 事务执行序列为T2执行完,再执行T1
| 事务T1 | 事务T2 | 数据A | 数据B |
|---|---|---|---|
| 25 | 25 | ||
| read(A,t) | |||
| t = t*2 | |||
| write(A,t) | 50 | ||
| read(B,t) | |||
| t = t*2 | |||
| write(B,t) | 50 | ||
| read(A,t) | |||
| t = t + 100 | |||
| write(A,t) | 150 | ||
| read(B,t) | |||
| t = t + 100 | |||
| write(B,t) | 150 |
从这两个事务的执行序列来看,初始状态一样,但是在不同的执行顺序下执行后的状态确不一样。两个事务串行执行的结果,与两个事务执行的顺序相关。
以上是两个事务串行执行的结果,当事务并发时,结果与串行执行一样吗?
- 两个事务并发执行中的一种可能序列
| 事务T1 | 事务T2 | 数据A | 数据B |
|---|---|---|---|
| 25 | 25 | ||
| read(A,t) | |||
| t = t + 100 | |||
| write(A,t) | 125 | ||
| read(A,t) | |||
| t = t*2 | |||
| write(A,t) | 250 | ||
| read(B,t) | |||
| t = t*2 | |||
| write(B,t) | 50 | ||
| read(B,t) | |||
| t = t + 100 | |||
| write(B,t) | 150 |
显然这次调度后的执行序列,得到的结果A=250,B=150,与上面两个事务串行执行的结果都不一样,最终状态是不一致的,所以这种调度是不可串行化的。
如何做到调度之后的可串行化,数据库通过可串行化的模型达到这一目标。
可串行化的模型
如果让多个事务简单的按装顺序来依次串行执行,一定是可以达到一致性的结果。多个事务的动作可以交叉,同时又与依次执行结果一样,这样的串行调度方式可以更高效的完成业务处理。
在大多数数据库中,采用封锁,时间戳和有效性确认,这三种方式组成的模型来达到并发事务可串行化,保证事务的特性。
总结
数据库并发控制的目标是,事务并发执行时,它们的执行序列可串行化,数据库的状态保持一致性。
在C语言中实现访问者模式,我们可以先定义一些结构体来表示元素对象和访问者对象。元素对象可以被访问者访问,而访问者对象可以访问元素对象并执行一些操作。
以下是一个简单的示例,其中定义了一个字符串类型的元素对象和一个输出字符串的访问者对象。在主函数中,我们创建了一个字符串类型的元素对象,然后使用访问者对象来访问它并输出 “Hello, world!”。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义字符串类型的元素对象
typedef struct Element {char* str;
} Element;// 定义输出字符串的访问者对象
typedef struct Visitor {void (*visit)(Element*);
} Visitor;// 定义一个函数,用于创建字符串类型的元素对象
Element* create_element(const char* str) {Element* element = (Element*)malloc(sizeof(Element));element->str = (char*)malloc(strlen(str) + 1);strcpy(element->str, str);return element;
}// 定义一个函数,用于销毁字符串类型的元素对象
void destroy_element(Element* element) {free(element->str);free(element);
}// 定义一个函数,用于执行输出字符串的操作
void visit_element(Visitor* visitor, Element* element) {visitor->visit(element);
}// 定义一个函数,用于创建输出字符串的访问者对象
Visitor* create_visitor() {Visitor* visitor = (Visitor*)malloc(sizeof(Visitor));visitor->visit = (void (*)(Element*))printf;return visitor;
}// 定义一个函数,用于销毁输出字符串的访问者对象
void destroy_visitor(Visitor* visitor) {free(visitor);
}int main() {// 创建一个字符串类型的元素对象,并赋值 "Hello, world!"Element* element = create_element("Hello, world!");// 创建一个输出字符串的访问者对象Visitor* visitor = create_visitor();// 使用访问者对象访问元素对象并输出 "Hello, world!"visit_element(visitor, element);// 销毁元素对象和访问者对象,释放内存资源destroy_element(element);destroy_visitor(visitor);return 0;
}
结尾
非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!
作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。
相关文章:
【数据库】数据库并发控制的目标,可串行化序列的分析,并发控制调度器模型
数据库并发控制 专栏内容: 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更…...
带头结点的双向循环链表
目录 带头结点的双向循环链表 1.存储定义 2.结点的创建 3.结点的初始化 4.尾插结点 5.尾删结点 6.头插结点 7.头删结点 8.查找并返回结点 9.在pos结点前插入结点 10.删除pos结点 11.打印链表 12.销毁链表 13.头插结点2.0版 14.尾插结点2.0版 前言: 当…...
2023年11月下旬大模型新动向集锦
2023年11月下旬大模型新动向集锦 2023.12.1版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 1、微软将向中国大陆开放Windows Copilot服务 据微软发布的消息,微软将在 2023 年 12 月 1 日面向中国大陆的企业和教育机构推出 We…...
有IP没有域名可以申请证书吗?
一、IP证书是什么? ip证书是用于公网ip地址的SSL证书,与我们通常所讲的SSL证书并无本质上的区别,但由于SSL证书通常颁发给域名,而组织机构需要公共ip地址的SSL证书,这类SSL证书就是我们所说的ip证书。ip证书具有安全、…...
【软件推荐】卸载360软件geek;护眼软件flux;
卸载360软件geek f.lux: software to make your life better (justgetflux.com) 卸载完扫描残留 护眼软件 hf.lux: software to make your life better (justgetflux.com)https://justgetflux.com/https://justgetflux.com/...
Module build failed: Error: ENOENT: no such file or directory
前言 这个错误通常发生在Node.js 和 vue,js项目中,当你试图访问一个不存在的文件或目录时。在大多数情况下,这是因为你的代码试图打开一个不存在的文件,或者你的构建系统(例如Webpack)需要一个配置文件,但找…...
Postgresql BatchInsert唯一键冲突及解决
Postgresql BatchInsert唯一键冲突及解决 当有唯一键冲突时,批量插入可能会报错; insert into tableA(sno,name,age,emp) values(),(),(); 会报错 insert into tableA(sno,name,age,emp) values(),(),() on conflict on contraint tableA_unique_key do …...
腾讯云AMD服务器标准型SA5实例AMD EPYC Bergamo处理器
腾讯云服务器标准型SA5实例是最新一代的标准型实例,CPU采用AMD EPYC™ Bergamo全新处理器,采用最新DDR5内存,默认网络优化,最高内网收发能力达4500万pps。腾讯云百科txybk.com分享腾讯云标准型SA5云服务器CPU、内存、网络、性能、…...
力扣 --- 加油站
题目描述: 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 给定两个…...
C++基础 -25- 动态多态
静态多态在程序编译的时候,确定将要执行的状态。 动态多态在程序运行的时候,才能确定执行的状态。 下面举例实现动态多态 work函数接口通过传参不同做不同的工作 #include "iostream"using namespace std;class person {public:person(){}vi…...
数据库-MySQL之数据库必知必会17-21章
第17章 组 合 查 询 创建组合查询 可用UNION操作符来组合数条SQL查询。利用UNION,可给出多条SELECT语句,将它们的结果组合成单个结果集。 **例子:**假如需要价格小于等于5的所有物品的一个列表,而且还想包括供应商1001和1002生产…...
mysql主从复制-redis集群扩容缩容、缓存优化(缓存更新策略、穿透,击穿,雪崩)、mysql主从搭建、django实现读写分离
基于Docker实现读写分离 1 redis集群扩容缩容 1.1 集群扩容 1.2 集群缩容 2 缓存优化 2.1 缓存更新策略 2.2 穿透,击穿,雪崩 3 mysql主从搭建 4 django实现读写分离 1 redis集群扩容缩容 1.1 集群扩容 # 6台机器,3个节点集群# 8台机器&am…...
docker部署kerberos,群晖nas中nfs开启kerberos校验
背景 nas开启nfs存储共享,默认情况下只能给IP/24做限制, 达不到安全效果 需要增加kerberos策略校验,并且持久化kerberos数据,避免容器重启丢失数据 环境描述 宿主机系统:CentOS Linux release 7.9.2009 (Core) Docker版本…...
【前端】数据行点击选择
前言 【前篇文章】说了,我们公司的核心价值就是让人越来越懒,能怎么便捷就怎么便捷,主打一个简单实用又快捷,为了实现这个目标,我看成这个列表陷入了深思在想,要不要子表的数据加载在点击这个行时,就可以展示数据,这样就不用每次都要点那个小圆圈啦。 查资料 这显然…...
网络安全技术
网络安全技术是一种保护网络系统免受攻击、破坏或未经授权访问的技术。它涵盖了一系列的方法和工具,旨在确保数据的完整性、可用性和保密性。以下是一些主要的网络安全技术: 1. 防火墙:防火墙是一种用于阻止未经授权的访问,同时允…...
这几款 idea 插件让效率起飞!
作者:苍何,前大厂高级 Java 工程师,阿里云专家博主,CSDN 2023 年 实力新星,土木转码,现任部门技术 leader,专注于互联网技术分享,职场经验分享。 🔥热门文章推荐…...
[FUNC]判断窗口在哪一个屏幕上
#Requires AutoHotkey v2.0#z:: { ToolTip "Notepad窗口所在显示屏是:" GetMonitor() } GetMonitor() {CoordMode("Mouse", "Screen"); MouseGetPos &mx, &myWinGetPos &mx, &my,,,"ahk_class Notepad"…...
Vue语音播报,不用安装任何包和插件,直接调用。
Vue语音播报功能可以通过使用浏览器提供的Web Speech API来实现。这个API允许你的应用程序通过浏览器朗读文本,不用安装任何包和插件,直接调用。以下是一个简单的介绍,演示如何在Vue中使用语音提示功能: 一、JS版本 <template…...
公网穿透和RTC
RTC RTC 是 Real-Time Communication 的简写,正如其中文名称 “即时通讯” 的意思一样,RTC 协议被广泛用于各种即时通讯领域,诸如: 在线教育;直播中的主播连麦 PK;日常生活的音视频电话;.....…...
uniapp 使用web-view外接三方
来源 前阵子有个需求是需要在原有的项目上加入一个电子签名的功能,为了兼容性和复用性后面解决方法是将这个电子签名写在一个新的项目中,然后原有的项目使用web-view接入这个电子签名项目; 最近又有一个需求,是需要接入第三方的…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
