Skip to content

SQLITE_OPEN_NOMUTEX 改为 SQLITE_OPEN_FULLMUTEX模式,确保外部锁&内部操作的原子性#172

Closed
hsjcom wants to merge 1 commit into
li6185377:masterfrom
hsjcom:fullMutex
Closed

SQLITE_OPEN_NOMUTEX 改为 SQLITE_OPEN_FULLMUTEX模式,确保外部锁&内部操作的原子性#172
hsjcom wants to merge 1 commit into
li6185377:masterfrom
hsjcom:fullMutex

Conversation

@hsjcom
Copy link
Copy Markdown

@hsjcom hsjcom commented Mar 13, 2026

一直有用户出现11 - database disk image is malformed 、14 - errorMessage:unable to open database file 等数据库损坏问题
#define LKDBOpenFlags (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_PRIVATECACHE | SQLITE_OPEN_FILEPROTECTION_NONE)
这里用的是SQLITE_OPEN_NOMUTEX,禁用了 SQLite 内部的互斥锁。是否可以把 SQLITE_OPEN_NOMUTEX 改为 SQLITE_OPEN_FULLMUTEX

因为业务的关系,会用到不同 GCD 对同一个 helper 实例的访问。虽然LKDBHelper 内部用 NSRecursiveLock 保护 executeDB: 方法,但这个锁只能防止同一线程的重入,不能有效协调不同 GCD 队列之间的并发访问。多个队列同时调用 executeDB: 时,锁虽然能串行化,但在 SQLITE_OPEN_NOMUTEX 下,FMDatabaseQueue 内部的 SQLite 连接本身没有互斥保护,仍然可能出问题。比如切换用户登录数据库切换,closeDB / openDB 之间的同步机制。OC 层的锁可能只保护了 SQLite 的调用,但没保护SQLite 内部行为,可能外部已经 closeDB,内部还在回写。改为 SQLITE_OPEN_NOMUTEX可以确保内部操作的原子性,性能影响较小。

@li6185377
Copy link
Copy Markdown
Owner

不应该直接修改默认行为, 我在 2.8.0 版本中开放了 dbOpenFlags 属性, 可以基于 onCreateWithLKDBHelper 回调,自行修改对应配置

@implementation LKDBUtils (MyConfig)
+ (void)onCreateWithLKDBHelper:(LKDBHelper *)dbHelper {
    dbHelper.dbOpenFlags = xxxx; // 修改数据库开启标识
}
@end

@li6185377 li6185377 closed this May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants