SQLite中的隔离(八)

news2024/10/5 15:27:15

 返回:SQLite—系列文章目录   

上一篇:SQLite版本3中的文件锁定和并发(七)

下一篇:SQLite—系列文章目录   

数据库的“isolation”属性确定何时对 一个操作的数据库对其他并发操作可见。

数据库连接之间的隔离

如果使用两个不同的数据库连接读取和写入同一个数据库(两个不同的 sqlite3 对象返回 单独调用 sqlite3_open()) 和两个数据库连接 没有共享缓存,则读取器只能 请参阅编写器的完整已提交事务。部分更改 作者没有承诺的对读者来说是不可见的。 无论两个数据库连接是否在 同一线程,在同一进程的不同线程中,或在 不同的过程。这 是 SQL 数据库系统的常见行为和预期行为。

上一段也是正确的(单独的数据库连接是 彼此隔离)在共享缓存模式下,只要read_uncommitted编译指示保持关闭状态即可。默认情况下,read_uncommitted编译指示处于关闭状态,因此,如果应用程序不执行任何操作来打开它, 它将保持关闭状态。因此,除非使用read_uncommitted编译指示 若要更改默认行为,请由一个数据库连接所做的更改 对于共享 相同的缓存,直到写入器提交其事务。

如果两个数据库连接共享同一个缓存,并且读取器具有 启用了read_uncommitted编译指示,然后读者将能够 请参阅编写器在编写器事务提交之前所做的更改。 共享缓存模式和read_uncommitted指示的组合使用是一个数据库连接可以查看未提交的更改的唯一方法 在不同的数据库连接上。在所有其他情况下,分开 数据库连接彼此完全隔离。

除了打开PRAGMA read_uncommitted共享缓存数据库连接的情况外,SQLite中的所有事务都显示 “可序列化”隔离。SQLite 实现可序列化事务 通过实际序列化写入。只能有一个作家 一次到一个 SQLite 数据库。可以有多个数据库连接 同时打开,所有这些数据库连接都可以写入 到数据库文件,但他们必须轮流。SQLite使用锁 自动序列化写入;这不是什么 使用SQLite的应用程序需要担心。

隔离和并发

SQLite 使用 与数据库文件位于同一目录中的暂时性日志文件。 有两种主要的“日志模式”。 较旧的“回滚模式”对应于使用“DELETE”、“PERSIST”、 或“TRUNCATE”选项添加到journal_mode编译指示中。在回滚模式下, 更改将直接写入数据库文件,同时 构造一个单独的回滚日志文件,该文件能够恢复 如果事务回滚,则数据库恢复到其原始状态。 回滚模式(特别是 DELETE 模式,即回滚日志 在每次事务结束时从磁盘中删除)是当前 默认行为。

从3.7.0版(2010-07-21)开始, SQLite还支持“WAL模式”。在 WAL 模式下, 更改不会写入原始数据库文件。相反,更改 进入单独的“预写日志”或“WAL”文件。 后来,交易后 提交时,这些更改将从 WAL 文件移回 原始数据库在名为“checkpoint”的操作中。WAL 模式是 通过运行“PRAGMA journal_mode=WAL”启用。

在回滚模式下,SQLite通过锁定数据库来实现隔离 文件并防止其他数据库连接读取 而每个写入事务都在进行中。 读者可以在写作开始时,在任何内容之前处于活动状态 刷新到磁盘,而所有更改仍保存在编写器的 专用内存空间。但在对数据库文件进行任何更改之前 在磁盘上,必须(暂时)驱逐所有读取器才能给写入器 对数据库文件的独占访问。 因此,禁止读者看到不完整的内容 由于被锁定在数据库之外的事务,而 事务正在写入磁盘。只有在交易之后 完全写入并同步到磁盘并提交是允许的读取器 返回到数据库中。因此,读者永远没有机会看到部分内容 书面更改。

WAL 模式允许同时读取和写入。它可以这样做,因为 更改不会覆盖原始数据库文件,而是执行 添加到单独的预写日志文件中。这意味着读者可以继续 从原始数据库文件中读取旧的、原始的、未更改的内容 同时,编写器将追加到预写日志中。 在WAL模式下,SQLite表现出“快照隔离”。当读取事务时 开始,该读者继续看到数据库的不变“快照” 文件,因为它在读取事务开始时存在。 在读取事务 active 对读取事务仍然不可见,因为读取器是 查看前一时刻的数据库文件快照。

举个例子:假设有两个数据库连接 X 和 Y。 使用 BEGIN 后跟一个或多个 SELECT 语句的读取事务。 然后 Y 出现并运行 UPDATE 语句来修改数据库。 X 随后可以对 Y 修改的记录执行 SELECT,但 X 将看到较旧的未修改条目,因为 Y 的更改都是 当 X 持有读取事务时,X 不可见。如果 X 想看 Y 所做的更改,则 X 必须结束其读取事务,并且 启动一个新的(通过运行 COMMIT,然后运行另一个 BEGIN)。

另一个示例:X 使用 BEGIN 和 SELECT 启动读取事务,然后 Y 使用 UPDATE 对数据库进行更改。然后 X 尝试做一个 使用 UPDATE 更改为数据库。X 试图升级其 从读取事务到写入事务的事务失败并显示SQLITE_BUSY_SNAPSHOT错误,因为数据库的快照正在 查看的 X 不再是数据库的最新版本。如果 X 是 允许写入,它将分叉数据库文件的历史记录,即 SQLite不支持的东西。为了让 X 写入数据库, 它必须首先发布其快照(例如使用 ROLLBACK),然后 使用后续 BEGIN 启动新事务。

如果 X 启动一个事务,该事务最初只会读取但 X 知道它 最终会想写,不想被烦恼 由于另一个连接而可能出现的SQLITE_BUSY_SNAPSHOT错误 在队列中跳到它前面,然后 X 可以发出 BEGIN IMMEDIATELY 来启动 它的交易而不仅仅是普通的 BEGIN。BEGIN IMMEDIATE 命令继续并启动写入事务,从而阻止所有 其他作家。如果 BEGIN IMMEDIATE 操作成功,则没有 该事务中的后续操作将失败并出现SQLITE_BUSY错误。

同一数据库连接上的操作之间没有隔离

SQLite 在单独的数据库中提供操作之间的隔离 连接。但是,操作之间没有隔离 发生在同一数据库连接中。

换言之,如果 X 使用 BEGIN IMMEDIATE 开始写入事务,然后发出一个或多个 UPDATE、DELETE 和/或 INSERT 语句,则这些更改对后续 SELECT 语句可见 在数据库连接 X 中计算的。 不同的数据库连接 Y 将不显示任何更改,直到 X 事务提交。但是 X 中的 SELECT 语句将显示更改 在提交之前。

在单个数据库连接 X 中,SELECT 语句始终看到所有 在 SELECT 开始之前完成的对数据库的更改 语句,无论是已提交的还是未提交的。和 SELECT 语句 显然看不到 SELECT 语句之后发生的任何更改 完成。但是,在 SELECT 语句中发生的更改呢? 正在跑步吗?如果启动了 SELECT 语句,并且 sqlite3_step() 接口单步执行了大约一半的输出,则某些 UPDATE 语句由修改表的应用程序运行,该 SELECT 语句正在读取,然后对 sqlite3_step() 进行更多调用 完成 SELECT 语句?将 SELECT 的后续步骤 声明是否看到 UPDATE 所做的更改?答案是 此行为未定义。特别是,无论 SELECT 语句是否 看到并发更改取决于 SQLite 的哪个版本 running,数据库文件的架构,无论 ANALYZE 是否具有 已运行,以及查询的详细信息。在某些情况下,这可能取决于 在数据库文件的内容上也是如此。没有好的方法可以知道是否 或者 SELECT 语句不会看到对数据库所做的更改 通过启动 SELECT 语句后的同一数据库连接。 因此,开发人员应该努力避免编写应用程序 对在这种情况下会发生什么做出假设。

如果应用程序在单个表上发出 SELECT 语句,例如 “SELECT rowid, * FROM table WHERE ...” 并开始单步执行 使用 sqlite3_step() 的该语句的输出并检查每个 行,则应用程序可以安全地删除当前行或 使用“DELETE FROM table WHERE rowid=?”的任何前行。它也是安全的 (从某种意义上说,它不会损害数据库)让应用程序 删除预计稍后在查询中出现但尚未出现的行 出现了。但是,如果删除了将来的行,则可能会发生以下情况 该行在随后的 sqlite3_step() 之后出现,即使在它有 据称已被删除。或者它可能不是。该行为是未定义的。 应用程序可以 此外,当 SELECT 语句 正在运行,但是否显示新行 在查询的后续 sqlite3_step() 中未定义。和应用程序 可以更新当前行或任何前一行,但这样做可能会导致 该行将在随后的 sqlite3_step() 中重新出现。只要 应用程序准备处理这些歧义,操作 它们本身是安全的,不会损害数据库文件。

就前两段而言,两个数据库连接 具有相同共享缓存且已启用 PRAGMA read_uncommitted的数据库连接被视为相同的数据库连接。

总结

  1. SQLite 中的事务是可序列化的。

  2. 在一个数据库连接中所做的更改对所有其他数据库都是不可见的 提交前的连接。

  3. 查询将查看在同一数据库连接上完成的所有更改 在查询开始之前,无论这些更改是否发生 已经提交。

  4. 如果查询后同一数据库连接发生更改 开始运行,但在查询完成之前,则不确定是否 或者查询不会看到这些更改。

  5. 如果查询后同一数据库连接发生更改 开始运行,但在查询完成之前,查询可能会返回 多次更改的行,或者它可能会返回以前更改的行 删除。

  6. 就前四项而言,两个数据库连接 使用相同的共享缓存,并且启用 PRAGMA read_uncommitted 被视为相同的数据库连接,而不是单独的数据库 连接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1553828.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

快速上手Spring Cloud 六:容器化与微服务化

快速上手Spring Cloud 一:Spring Cloud 简介 快速上手Spring Cloud 二:核心组件解析 快速上手Spring Cloud 三:API网关深入探索与实战应用 快速上手Spring Cloud 四:微服务治理与安全 快速上手Spring Cloud 五:Spring …

独立站如何采集商品?外贸独立站采集教程

最近和一位仿牌的卖家聊天,他想建个站做日本市场。除了产品素材、suk以外其它都能搞定,找到我帮忙。从这里Robert了解到还有国内有很多仿牌卖家、微商,都有类似的情况,他们出海的阻碍主要在于支付、物流、推广。只要解决了这些问题…

机器学习-生存分析:基于QHScrnomo模型的乳腺癌患者风险评估与个性化预测

一、引言 乳腺癌作为女性常见的恶性肿瘤之一,对女性健康构成威胁。随着医疗技术的不断进步,个性化医疗逐渐成为乳腺癌治疗的重要方向。通过深入研究乳腺癌患者的风险评估和个性化预测,可以帮助医生更准确地制定治疗方案,提高治疗效…

2024蓝桥杯每日一题(背包2)

备战2024年蓝桥杯 -- 每日一题 Python大学A组 试题一:包子凑数 试题二:砝码称重 试题三:倍数问题 试题一:包子称重 【题目描述】 小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有 N 种蒸笼&#xf…

vue中使用jsmind生成脑图

项目部分参数&#xff1a; vue&#xff1a;2.6.10 node:16.20.0 1、使用命令行安装jsmind&#xff1a; npm i jsmind -S 2、在文件中引入jsmind&#xff0c;并编写渲染jsmind的代码&#xff1a;&#xff1a; <template><!-- jsmind容器 --><divid"jsmi…

动态规划入门(数字三角形模型)

备战2024年蓝桥杯&算法学习 -- 每日一题 Python大学A组 试题一&#xff1a;摘花生 试题二&#xff1a;最低通行费用 试题三&#xff1a;方格取数 试题四&#xff1a;传纸条 试题一&#xff1a;摘花生 【题目描述】 Hello Kitty想摘点花生送给她喜…

kubernetes(K8S)学习(六):K8S之Dashboard图形界面

K8S之Dashboard图形界面 一、Dashboard简介二、k8s安装Dashboard(1)下载Dashboard镜像&#xff08;可选&#xff09;(2)根据yaml文件创建资源(3)查看资源(4)生成登录需要的token(5)使用火狐 / 搜狗浏览器访问&#xff08;个人用的搜狗&#xff09; 一、Dashboard简介 官网&…

Aurora IP的Framing帧接口和Streaming流接口

本文介绍Aurora IP配置时要选择的接口类型以及两种接口类型之前的区别。 Aurora IP接口有两种模式&#xff1a;Framing帧接口&#xff0c;Streaming流接口 目前一直在用的都是Framing帧接口。 Framing帧接口和Streaming流接口的主要区别是什么呢&#xff1f; 顾名思义&#x…

代码随想录笔记|C++数据结构与算法学习笔记-栈和队列(〇)|stack、queue、单调队列和优先级队列(priority_queue)、大顶堆和小顶堆

文章目录 stack容器stack 基本概念常用接口构造函数赋值操作数据存取大小操作 queue容器queue常用接口构造函数&#xff1a;赋值操作数据存取大小操作 单调队列定义实现代码实现 基本应用一&#xff1a;滑动窗口思路与算法 优先级队列定义大顶堆&#xff08;最大堆&#xff09;…

1.5-数组-059. 螺旋矩阵 II★★

59. 螺旋矩阵II ★★ 力扣题目链接&#xff0c;给你一个正整数 n &#xff0c;生成一个包含 1 到 n 2 n^2 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。1 < n < 20 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[[1,…

【大数据运维】minio 常见shell操作

文章目录 1. 安装2. 入门操作3. 命令帮助 1. 安装 下载 https://dl.min.io/client/mc/release/linux-amd64/ 赋权与使用 cp mc /usr/bin && chmod x /usr/bin/mc ./mc --help 2. 入门操作 # 添加minio到mc mc config host add minio_alias_name endpoint_adress …

成都市酷客焕学新媒体科技有限公司:实现品牌的更大价值!

成都市酷客焕学新媒体科技有限公司专注于短视频营销&#xff0c;深知短视频在社交媒体中的巨大影响力。该公司巧妙地将品牌信息融入富有创意和趣味性的内容中&#xff0c;使观众在轻松愉悦的氛围中接受并传播这些信息。凭借独特的创意和精准的营销策略&#xff0c;成都市酷客焕…

2024 蓝桥打卡Day25

CCFCSP算法练习 202305-1 重复局面 202305-2 矩阵运算 202303-1 田地丈量 202303-2 垦田计划

C++王牌结构hash:哈希表闭散列的实现与应用

一、哈希概念 顺序结构以及平衡树中&#xff0c;元素关键码与其存储位置之间没有对应的关系&#xff0c;因此在查找一个元素 时&#xff0c;必须要经过关键码的多次比较。顺序查找时间复杂度为O(N)&#xff0c;平衡树中为树的高度&#xff0c;即O(log n)&#xff0c;搜索的效率…

尾矿库在线安全监测:提升矿山安全水平

在矿山安全领域&#xff0c;尾矿库的安全管理尤为关键。尾矿库作为矿山生产链条的重要环节&#xff0c;其稳定性不仅关系到生产活动的持续进行&#xff0c;更直接影响着周边环境和人民群众的生命财产安全。因此&#xff0c;尾矿库的安全监测显得尤为重要。近年来&#xff0c;随…

全球首个“AI程序员”Deven能替代程序员吗?过了面试却不一定适合职场

制造Devin的公司&#xff0c;是一家叫Cognition的10人初创公司&#xff0c;才成立不到2个月。 一、引言 一家成立不到两个月但拥有十名天才工程师的初创公司Cognition&#xff0c;搞了一个引爆科技圈的大动作。 他们推出了一款名为Devin的人工智能&#xff08;AI&#xff09;助…

【Python函数和类2/6】函数的参数

目录 目标 为函数设置参数 传递实参 关键字实参 关键字实参的顺序 位置实参 常见错误 缺少实参 位置实参的顺序 默认值形参 参数的优先级 默认值形参的位置 总结 目标 上篇博客中&#xff0c;我们在定义函数时&#xff0c;使用了空的括号。这表示它不需要任何信息就…

IDEA2021.1.2破解无限试用30天破解IDEA

安装包下载 IDEA安装包&#xff1a;Other Versions - IntelliJ IDEA破解包下载&#xff1a;文件 密码:c033 开始激活 IDEA 2021.1.3 运行, 中间会先弹出一个注册框&#xff0c;我们勾选 Evaluate for free, 点击 Evaluate&#xff0c; 先试用30天: 注意&#xff0c;如果没有…

Leo赠书活动-22期 【大模型在金融行业的应用场景和落地路径】文末送书

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…

对form表单对象中数组中的字段进行校验的方法

当对form表单中&#xff0c;数组readings中的字段进行校验时&#xff0c;prop和rules绑定要写成动态的&#xff0c;如下代码 <div v-for"(item,index) in form.readings"><el-form-item label"上次读数" > <!--prop"scds"-->…