badgerdb里面的事务
事务的ACID
-
A 原子性(Atomicity)
多步骤操作,只能是两种状态,要么所有的步骤都成功执行,要么所有的步骤都不执行,举例说明就是小明向小红转账30元的场景,拆分成两个步骤,步骤1:小明减30元。步骤2:小红加30元。步骤1和2必须同时执行成功或失败,不能只执行其中的一个步骤。 -
C 一致性(Consistency)
其实和原子性一样 -
I 隔离性(Isolation)
多个事务执行时,不能受并发的事务的影响,后面会详细的说隔离级别 -
D 持久性(Durability)
事务一旦提交落盘后,数据不会因为程序异常或断电丢失数据
隔离性
- 读未提交(Read uncommitted)
- 读已提交(Read committed)
- 可重复读(Repeatable read)
- 序列化(Serializable )
从上到下,四个级别的隔离性依次变强,性能依次变差

读未提交 :对应脏读,在本事务的线段内,会读到其他线段的中间状态。
读已提交:对应不可重复读,比上个好一些。该级别下不能读到其他事务的未提交状态。但如上图,如果事务 t2 在执行时,多次读某个记录 x 的状态,在事务 t1 未启动前,发现 x = 2,在事务 t1 提交后,发现 x = 3,这便出现了不一致。
可重复读:如上图,事务 t2 在整个执行期间,多次读取数据库 x 的状态,无论他事务(如 t1)是否改变 x 状态并提交,事务 t2 都不会感觉到。但是会存在幻读的风险。怎么理解呢?最关键的原因在于写并发。因为读不到,不代表其他事务的影响不存在。比如事务 t2 开始时,通过查询发现 id = “qtmuniao” 的记录为空,于是创建了 id=“qtmuniao” 的记录,然而在提交时,发现报错说该 id 已经存在。这可能是因为有一个开始的比较晚的事务 t2,也创建了一个 id=“qtmuniao” 的记录,但是先提交了。于是用户就郁闷了,明明你说没有,但我写又报错,难道我出现幻觉了?这就太扯淡了,但是此级别就只能做到这样了。反而,因为兼顾了性能和隔离性,他是大多数据库的默认级别。
序列化:最简单的实现办法就是一把锁来串行化所有的事务boltdb就是这么做的。badgerdb在此基础上如果能提高并发,做很多优化。
badger 的序列化SSI
badgerdb 的事务主要依靠多个tnx结构体和全局的一个oracle结构体来维护
type Txn struct {readTs uint64commitTs uint64
}type oracle struct {nextTxnTs uint64
}
每一个txn都有readTs和commitTs ,其中全局的o.nextTxnTs只有获得提交时间戳的时候才加1,如果多个事务并发,任何一个事务都还没有提交的时候,这些事务获得的readTs 是一样的
var readTs uint64o.Lock()readTs = o.nextTxnTs - 1//txn 的readTso.readMark.Begin(readTs)o.Unlock()ts = o.nextTxnTso.nextTxnTs++//事务获得了提交时间后,再把nextTxnTs+1o.txnMark.Begin(ts)
创建一个事务的时候,要进行授时txn.readTs = db.orc.readTs(),这个时间是一个递增的序列,接下来主要来分析一下db.orc.readTs()这个函数,获得readTs后会等待readTs这个时间戳提交的事务彻底写入LSM tree后才返回,保证了不会脏读,不会读到其他未提交的事务,和不可重复读
func (o *oracle) readTs() uint64 {if o.isManaged {panic("ReadTs should not be retrieved for managed DB")}var readTs uint64o.Lock()readTs = o.nextTxnTs - 1o.readMark.Begin(readTs)o.Unlock()// Wait for all txns which have no conflicts, have been assigned a commit// timestamp and are going through the write to value log and LSM tree// process. Not waiting here could mean that some txns which have been// committed would not be read.y.Check(o.txnMark.WaitForMark(context.Background(), readTs))return readTs
}
badgerdb 解决幻读
在上文描述的可重复读,出现的幻读,badgerdb解决幻读和不可重复读的方法就是事务t2放弃提交,给用户层返回ErrConflict错误,让用户层稍后再试。
先找到代码中报ErrConflict的地方,是获取CommitTs的时候报的错误
func (txn *Txn) commitAndSend() (func() error, error) {orc := txn.db.orc// Ensure that the order in which we get the commit timestamp is the same as// the order in which we push these updates to the write channel. So, we// acquire a writeChLock before getting a commit timestamp, and only release// it after pushing the entries to it.orc.writeChLock.Lock()defer orc.writeChLock.Unlock()commitTs, conflict := orc.newCommitTs(txn)if conflict {return nil, ErrConflict}
}
进去看orc.newCommitTs(txn)
func (o *oracle) newCommitTs(txn *Txn) (uint64, bool) {o.Lock()defer o.Unlock()if o.hasConflict(txn) {return 0, true}
}
再看o.hasConflict(txn);
txn.reads 是被txn.addReadKey进行修改的;
committedTxn.conflictKeys 是txn.modify() 修改的,txn.modify()是txn.Set或txn.Detele调用的;
总结下来就是:当前事务如果读过的key,在当前事务的readTs后有在其他的事务对这些读到过的key做过修改,那么本次事务就是有冲突的
// hasConflict must be called while having a lock.
func (o *oracle) hasConflict(txn *Txn) bool {if len(txn.reads) == 0 {return false}for _, committedTxn := range o.committedTxns {// If the committedTxn.ts is less than txn.readTs that implies that the// committedTxn finished before the current transaction started.// We don't need to check for conflict in that case.// This change assumes linearizability. Lack of linearizability could// cause the read ts of a new txn to be lower than the commit ts of// a txn before it (@mrjn).if committedTxn.ts <= txn.readTs {continue}for _, ro := range txn.reads {if _, has := committedTxn.conflictKeys[ro]; has {return true}}}return false
}
相关文章:
badgerdb里面的事务
事务的ACID A 原子性(Atomicity) 多步骤操作,只能是两种状态,要么所有的步骤都成功执行,要么所有的步骤都不执行,举例说明就是小明向小红转账30元的场景,拆分成两个步骤,步骤1&#…...
C# this.Invoke(new Action(() => { /* some code */ }))用法说明
在 C# 中,this.Invoke(new Action(() > { /* some code */ })) 是一种用于在 UI 线程上执行代码的方法,通常用于在后台线程中更新 UI 控件的值或执行其他需要在 UI 线程上执行的操作。 在 Windows Forms 或 WPF 等图形界面应用程序中,UI …...
MongoDB:MySQL,Redis,ES,MongoDB的应用场景
简单明了说明MySQL,ES,MongoDB的各自特点,应用场景,以及MongoDB如何使用的第一章节. 一. SQL与NoSQL SQL被称为结构化查询语言.是传统意义上的数据库,数据之间存在很明确的关联关系,例如主外键关联,这种结构可以确保数据的完整性(数据没有缺失并且正确).但是正因为这种严密的结…...
leetcode每日一题_2682.找出转圈游戏输家
2682.找出转圈游戏输家 题目: n 个朋友在玩游戏。这些朋友坐成一个圈,按 顺时针方向 从 1 到 n 编号。从第 i 个朋友的位置开始顺时针移动 1 步会到达第 (i 1) 个朋友的位置(1 < i < n),而从第 n 个朋友的位置开始顺时针移…...
OpenCV之薄板样条插值(ThinPlateSpline)
官方文档:OpenCV: cv::ThinPlateSplineShapeTransformer Class Reference 使用方法: 头文件:#include <opencv2/shape/shape_transformer.hpp> (1)点匹配 一般根据有多少个样本(或者点)…...
034_小驰私房菜_[问题复盘] Qcom平台,某些三方相机拍照旋转90度
全网最具价值的Android Camera开发学习系列资料~ 作者:8年Android Camera开发,从Camera app一直做到Hal和驱动~ 欢迎订阅,相信能扩展你的知识面,提升个人能力~ 【一、问题】 某些三方相机,预览正常,拍照旋转90度 【二、问题排查】 1 ) HAL这边Jpeg编码数据在哪个地方…...
【TI-CCS笔记】工程编译配置 bin文件的编译和生成 各种架构的Post-build配置汇总
【TI-CCS笔记】工程编译配置 bin文件的编译和生成 各种架构的Post-build配置汇总 TI编译器分类 在CCS按照目录下 有个名为${CG_TOOL_ROOT}的目录 其下就是当前工程的编译器 存放目录为: C:\ti\ccs1240\ccs\tools\compiler按类型分为五种: ti-cgt-arm…...
深入探索Java中的File类与IO操作:从路径到文件的一切
文章目录 1. File类的作用与构造方法2. File类常用方法:获取、判断和创建2.1 获取功能方法2.2 判断功能方法2.3 创建和删除功能方法2.4 目录的遍历方法 3. 递归:探索更深的层次代码示例:递归遍历文件夹 结论 🎉欢迎来到Java学习路…...
Python 处理 Excel 表格的 14 个常用操作
目录 1. 安装依赖库 2. 导入库 3. 读取Excel文件 4. 写入Excel文件 5. 创建工作表 6. 访问工作表 7. 读取单元格数据 8. 写入单元格数据 9. 获取行数和列数 10. 过滤数据 11. 排序数据 12. 添加新行 13. 删除行或列 14. 计算汇总统计 总结 无论是数据分析师、财…...
PyQt有哪些主要组件?
这是一个非常强大的跨平台GUI库,可以让你用Python语言创建美观且功能强大的桌面应用程序。让我们先来了解一下它的主要组件。 首先,我们要介绍的是窗口。窗口是PyQt应用程序的基本元素,所有的GUI元素都放置在窗口中。你可以创建主窗口、模态…...
力推C语言必会题目终章(完结篇)
W...Y的主页 😊 代码仓库分享 💕 今天是分享C语言必会题目最终章,全部都是硬货,大家都坐好准备开始喽!!! 编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内…...
CS5263替代停产IT6561连接DP转HDMI音视频转换器ASL 集睿致远CS5263设计电路原理图
ASL集睿致远CS5263是一款DP1.4到HDMI2.0b转换器芯片,设计用于将DP1.4源连接到HDMI2.0b接收器。 CS5263功能特性: DP接口包括4条主通道、辅助通道和HPD信号。接收器支持每通道5.4Gbps(HBR2)数据速率。DP接收机结合了HDCP1.4和HDCP…...
数据分析 | 随机森林如何确定参数空间的搜索范围
1. 随机森林超参数 极其重要的三个超参数是必须要调整的,一般再加上两到三个其他超参数进行优化即可。 2. 学习曲线确定n_estimators搜索范围 首先导入必要的库,使用sklearn自带的房价预测数据集: import numpy as np import pandas as pd f…...
5G+AI数字化智能工厂建设解决方案PPT
导读:原文《5GAI数字化智能工厂建设解决方案》(获取来源见文尾),本文精选其中精华及架构部分,逻辑清晰、内容完整,为快速形成售前方案提供参考。数字化智能工厂定义 智能基础架构协同框架 - 端、边、云、网…...
Windows配置编译ffmpeg +音视频地址
Windows配置MinGW及MinGW-make使用实例 https://blog.csdn.net/Henoiiy/article/details/122550618 ffmpeg安装遇错:nasm/yasm not found or too old. Use --disable-x86asm for a crippled build. https://blog.csdn.net/sayyy/article/details/124337834https://…...
C语言 常用工具型API --------system()
函数名: system() 用 法: int system(char *command); 原理: 加载一个子进程去执行指定的程序,而想Linux命令基本都是一个单独的进程实现的,所以你所掌握的Linux命令越多,该函数功…...
车规级半导体分类(汽车芯片介绍)
车规级半导体,也被称为“汽车芯片”,主要应用于车辆控制装置、车载监控系统和车载电子控制装置等领域。这些半导体器件主要分布在车体控制模块上,以及车载信息娱乐系统方面,包括动力传动综合控制系统、主动安全系统和高级辅助驾驶…...
opencv图像轮廓检测
效果展示: 代码部分: import cv2 import numpy as np img cv2.imread(C:/Users/ibe/Desktop/picture.PNG,cv2.IMREAD_UNCHANGED) # 类型转换 img cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 结构元 kernel cv2.getStructuringElement(cv2.MORPH_REC…...
诚迈科技荣膺小米“最佳供应商奖”
近日,诚迈科技受邀参加小米战略合作伙伴HBR总结会。诚迈科技以尽职尽责的合作态度、精益求精的交付质量荣膺小米公司颁发的最佳供应商奖,其性能测试团队荣获优秀团队奖。 诚迈科技与小米在手机终端方向一直保持着密切的合作关系,涉及系统框架…...
分布式 - 消息队列Kafka:Kafka 消费者的消费位移
文章目录 01. Kafka 分区位移02. Kafka 消费位移03. kafka 消费位移的作用04. Kafka 消费位移的提交05. kafka 消费位移的存储位置06. Kafka 消费位移与消费者提交的位移07. kafka 消费位移的提交时机08. Kafka 维护消费状态跟踪的方法 01. Kafka 分区位移 对于Kafka中的分区而…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
