我在Python中开发了一个基本的代理测试器.代理IP和端口以及它们的date_of_last_test(例如31/12/2011 10:10:10)和result_of_last_test(OK或KO)存储在单个SQLite表中. (我意识到我可以在测试结果中存储更多细节并保留历史/统计数据,但这个简单的模型适合我的需要).
这是测试人员主循环的简化代码,我循环代理并更新其状态:
while True:
# STEP 1: select
myCursor.execute("SELECT * from proxy ORDER BY date_of_last_test ASC;")
row = myCursor.fetchone()
# STEP 2: update
if isProxyWorking(row['ip'], row['port']): # this test can last a few seconds
updateRow(row['ip'], row['port'], 'OK')
else:
updateRow(row['ip'], row['port'], 'KO')
我的代码作为单个进程运行时工作正常.现在,我希望能够使用相同的SQLite数据库文件运行该程序的许多进程.
当前代码的问题是缺少一种阻止多个进程测试同一代理的锁定机制.
在STEP 1 / SELECT时间对行进行锁定的最简洁方法是什么,以便执行SELECT的下一个进程获得下一行?
换句话说,我想避免以下情况:
假设它是10PM,DB包含2个代理:
代理A最后一次在晚上8点测试,代理B在晚上9点测试.
我启动测试人员的两个过程来更新他们的状态:
> 10:00 – 进程1获取“最老的”代理来测试它:A
> 10:01 –
进程2获取“最老的”代理来测试它:!!!一种 !!! (我在这里
像过程2获得代理B因为A已经在测试 –
虽然在db中尚未更新)
> 10:10 – 过程1对A的测试是
结束,其状态在DB中更新
> 10:11 – 过程2对A的测试是
结束,它的状态在DB中更新(!!! AGAIN !!!)
在这种情况下没有实际的错误/异常,但是我想避免浪费时间.
解决方法:
SQlite只允许一个进程一次更新数据库中的任何内容,从FAQ开始
Multiple processes can have the same database open at the same time. Multiple processes can be doing a SELECT at the same time. But only one process can be making changes to the database at any moment in time,
和
When SQLite tries to access a file that is locked by another process, the default behavior is to return SQLITE_BUSY. You can adjust this behavior from C code using the sqlite3_busy_handler() or sqlite3_busy_timeout() API functions.
因此,如果只有少量更新,那么这将有效,否则您需要更改为功能更强大的数据库.
所以整个数据库中只有一个锁
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!