当前位置: 首页 > 工具软件 > go-sqlite3 > 使用案例 >

go-sqlite3 “database is locked”问题解决方案

鞠泰平
2023-12-01

1 背景

rds创建集群后进行启动或者停止操作时,会造成sqlite的写入产生死锁,无法进行后续的写入。

2 问题

sqlite3数据库在写入操作时,如果多路同时写入可能会造成“database is locked”的死锁问题。

3 测试

进行单元测试,在测试文件创建一个db服务,起1000个goroutine向nerv.db中不停地写入数据,在写入数据的同时对数据库中进行查询操作,会出现2种情况:

数据库报“Error: database is locked”,程序无影响继续写入数据;
数据库查询成功,程序报:
time=“2019-09-09T11:18:02+08:00” level=error msg=“failed to save app. path=iy903,err:database is locked” file=“repository/app_repository.go:26”
Register error. failed to save. err:database is locked

4 解决方案

4.1 添加读写锁

在进行sqlite的写操作的函数中加入读写锁,进行测试。

4.2 添加到DSN: cache=shared

在config.json文件db/url中更改为

“…/data/nerv.db?cache=shared”,测试报死锁错误,排除。

4.3 设置db.SetMaxOpenConns(1)

发现底层已经做了这种操作,排除。

4.4 defer db.close()

添加defer db.close(),发现公共库已经在container中已经作了相关处理,排除。

4.5 db.Exec(“PRAGMA journal_mode=WAL;”)

执行 db.Exec(“PRAGMA journal_mode=WAL;”)

或者是在sql.Open()中加入例如为:"file:mydbfile.db?cache=shared&mode=rwc&_journal_mode=WAL"的参数

执行后会出现一个问题,原来的数据库文件变为3个文件,nerv.db内的数据丢失。

4.6 在写入前后分别增加db.Begin()和db.commit()

执行,到一定程度后,程序停在一个状态无法再次执行。查看数据发现,没有数据的写入。排除。

4.7 添加&_busy_timeout=9999999

在sql.Open()后添加&_busy_timeout=9999999 的参数。测试暂无报错情况出现。

 类似资料: