当前位置:首页 > 数据库 > SQlite

用SQLite锁定一行(读锁?)

我在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)!