cla*_*ayg 13 python sqlite sqlalchemy
昨天我正在使用一些需要"选择...更新"概念的sqlalchemy东西来避免竞争条件.添加.with_lockmode('update')
到查询对InnoDB和Postgres有效,但对于sqlite,我最终不得不潜入
if session.bind.name == 'sqlite':
session.execute('begin immediate transaction')
Run Code Online (Sandbox Code Playgroud)
在做选择之前.
这似乎现在有效,但感觉就像作弊.有一个更好的方法吗?
SELECT ... FOR UPDATE OF ...不受支持.考虑到SQLite的机制,这是可以理解的,因为在更新任何位时整个数据库被锁定,因此行锁定是多余的.但是,如果SQLite的未来版本支持SQL for interchageability,那将是一件好事.唯一需要的功能是确保数据库上存在"保留"锁定(如果尚未存在).
摘自 http://sqlite.org/cvstrac/wiki?p=UnsupportedSql
我认为你必须同步访问整个数据库.正常的同步机制也应该适用于文件锁,进程同步等
小智 6
我认为 SELECT FOR UPDATE 与 SQLite 相关。在我开始写入之前无法锁定数据库。到那时就太晚了。这是场景:
\n我有两台服务器和一个数据库队列表。每个服务器都在寻找工作,当它找到一个工作时,它会用“我得到它\xe2\x80\x9d”来更新队列表,这样其他服务器就不会\xe2\x80\x99t也找到它相同的工作。我需要将记录留在队列中以防恢复。
\n服务器 1 读取第一个无人认领的项目并将其保存在内存中。服务器 2 读取相同的记录并且现在也将其存储在内存中。然后,服务器 1 更新记录,锁定数据库,更新,然后解锁。然后,服务器 2 锁定数据库、更新并解锁。结果是两台服务器现在都在执行相同的工作。该表显示服务器 2 有更新,而服务器 1 更新丢失。
\n我通过创建锁定数据库表解决了这个问题。服务器 1 开始一个事务,写入锁定数据库以进行写入的锁定表。服务器 2 现在尝试开始事务并写入锁定表,但被阻止。服务器 1 现在读取第一个队列记录,然后使用 \xe2\x80\x9cI got it\xe2\x80\x9d 代码更新它。然后删除刚刚写入锁表的记录,提交并释放锁。现在服务器 2 能够开始其事务,写入锁定表,读取第二条队列记录,用其 \xe2\x80\x9c 更新它我得到它\xe2\x80\x9d 代码,删除它\xe2\x80\x99s锁定记录、提交并且数据库可用于下一个寻找工作的服务器。
\n 归档时间: |
|
查看次数: |
5970 次 |
最近记录: |