我之前曾观察到,当我绕过原子事务(django)时,sqlite db写入速度明显更快 - 0.3秒没有,而事务处理时间为0.004秒。因此,我在整个项目中应用了交易。奇怪的是,在我这样做后,我开始遇到'数据库已被锁定'错误,这导致我调试它以发现当更新在事务上运行时(让我们称之为更新A)并且当我尝试同时运行另一个更新时(B)在一个事务上然后它立即失败而不等待超时(默认为5秒)。但是当我尝试在没有事务的情况下运行更新B时,它等待A完成然后完成更新。任何人都可以向我提供一个可能的解释,其中不包括删除交易。
答案 0 :(得分:0)
可以使用PRAGMA busy_timeout设置SQLite的超时。
默认值为零,此设置仅适用于连接(不适用于数据库),因此看起来并非所有连接都获得了5秒。
通过执行PRAGMA确保所有连接都设置了正确的超时。 (五秒钟是危险的;最好使用三十秒。)
答案 1 :(得分:0)
发生这种情况的原因有两个:
transaction.atomic()
开始进行DEFERRED
事务,因此一开始就没有锁。例如:
# no lock is acquired here because it executes BEGIN query which
# defaults to BEGIN DEFERRED
with transaction.atomic():
# this acquires read lock on DB
MyModelName.objects.all().first()
# this tries to change read lock to write lock
# but fails because another process is holding a write lock
MyModelName.objects.create(name='Example')
# "OperationalError: database is locked" is raised here
# immediately ignoring the timeout
我不完全确定为什么会发生这种情况,但是我发现另一则帖子说这可能是由于僵局造成的:
sqlite3 ignores sqlite3_busy_timeout?
因此,您的选择是:
transaction.atomic()
立即获得写锁,如btimby在此处所述:Fix SQLite "database is locked" problems using "BEGIN IMMEDIATE"