AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 345265
Accepted
Alex
Alex
Asked: 2025-02-13 21:10:09 +0800 CST2025-02-13 21:10:09 +0800 CST 2025-02-13 21:10:09 +0800 CST

当数据库有其他读取者时,Sqlite 事务未释放

  • 772

如果我有多个数据库读取器,它们基本上是以“读取”模式打开数据库文件的 Sqlite 实例,那么对于以“创建”模式打开数据库的单个写入器来说,在所有读取器关闭数据库之前无法释放事务,这正常吗?

我试图弄清楚这是 sqlite 的正常行为,还是我正在使用的特定 sqlite 库的错误/限制。

我不明白为什么作者需要等待读者停止使用数据库文件,这对我来说没有意义,因为读者无法更改数据

sqlite
  • 3 3 个回答
  • 39 Views

3 个回答

  • Voted
  1. Best Answer
    White Owl
    2025-02-17T08:30:04+08:002025-02-17T08:30:04+08:00

    不可以。在所有读者退出数据库之前,你的写入器无法释放事务,这是不正常的。

    这就引出了一个问题:你究竟如何打开数据库文件?

    sqlite 引擎确实有以只读模式打开数据库的能力: https://www.sqlite.org/c3ref/open.html

    sqlite3 *db;
    sqlite3_open_v2("mydb.dat", &db, SQLITE_OPEN_READONLY, NULL);
    

    但是默认标志(第三个参数)是SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE。

    如果有一个应用程序以正常方式打开文件SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE。并且有多个应用程序以模式打开SQLITE_OPEN_READONLY,则写入器不应等待读取器。它甚至不知道它们。

    sqlite3如果可以,请尝试使用控制台工具进行查询。它有一个--readonly选项,可以真正以只读模式打开数据库文件。

    但是,如果您不是使用 C 语言,而是使用某种语言绑定,则文件可能会始终正常打开,然后在绑定级别切换到只读模式。


    从形式上看,该select语句可以对表模式进行锁定,这样当一个用户alter table正在从表中进行选择时,另一个用户就无法执行任何操作。但这是读者可以对表进行锁定的唯一真正方法。

    sqlite只读模式下的唯一锁是为了防止数据库文件被删除。


    阅读有关共享缓存模式的文章也很有帮助:https://www.sqlite.org/sharedcache.html在某些情况下可以做到这一点,并且如果事务基于相同的缓存,它还可以干扰事务。

    • 1
  2. Mike Sherrill 'Cat Recall'
    2025-02-14T00:24:41+08:002025-02-14T00:24:41+08:00

    我不明白为什么作者需要等待读者停止使用数据库文件

    因为每个 SQLite 事务(隐式或显式)都会锁定数据库文件。

    除事务之外,不会发生任何读取或写入。 事务

    您可以通过在连接到同一 SQLite 数据库文件的两个不同终端会话中运行 SQLite3 来测试这一点。确切的行为取决于几个细节,尤其是“预写日志”(WAL) 选项。再次参见事务

    写入者不会“释放”事务;它们要么提交,要么回滚。例如,如果写入者试图提交插入语句,而另一个进程打开了一个选择事务(即正在“读取数据库”),则写​​入者会在我的计算机上收到此错误。

    [snip]
    sqlite> commit;
    Error: stepping, database is locked (5)
    
    • 0
  3. J.D.
    2025-02-14T01:18:40+08:002025-02-14T01:18:40+08:00

    除了 Mike 所说的之外,关于您的想法:

    我不明白为什么作者需要等待读者停止使用数据库文件,这对我来说没有意义,因为读者无法更改数据

    当然,但是写入者确实会改变数据库,并且如果读取者正在读取数据并且写入者更改了其中的一些数据,则可能会出现读取者无法预料的结果。

    例如,如果读取查询正在扫描索引中的每一行,那么对于想要更新键值的写入者来说,如果该键值会改变该索引中行的位置,那么必须等到读取者完成扫描索引才有意义。否则,读取者可能会两次重新读取同一数据行,并返回不准确的结果。这称为不可重复读取。

    可能发生的另一个问题是脏就绪,即读取器尚未完成扫描索引,写入器对某一行进行了更改,然后读取器读取该行,而写入器的事务被回滚(撤消/未提交),导致读取器读取的数据从未保存到数据库中,从而导致不准确。

    这些非常简单的示例是为什么除了写入器也会阻塞读取器之外,读取器通常会阻塞写入器的一些原因。存在隔离级别和乐观并发的概念,允许写入器和读取器在同时操作同一数据时不相互阻塞。但是,使用此类功能的能力在每个数据库系统的实现中有所不同,我不确定 SQLite 是否提供了此功能。

    • 0

相关问题

  • 在 SQLite 上写入一行需要多少次磁盘寻道?

  • SQLite 是否有可用于数据复制的免费软件?[关闭]

  • 在客户端应用程序上使用 CoreData

  • SQLite 的限制

  • 是否可以将 SQLite 用作客户端-服务器数据库?[关闭]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve