sqlite - 在 Python 中锁定一个 sqlite3 数据库(重新要求澄清)

标签 sqlite

几周前,我在 SO 上发布了这个关于如何在 python 中锁定 sqlite3 数据库的问题:

How to lock a sqlite3 database in Python?

但是,我不太相信答案是否有效。或者,也许我只是误解了答案。

这是我遇到的情况:

  • 我有一个数据库“test”
  • 在数据库“test”中有一个表“book”
  • 在“book”表中有两列:“title”和“checked_out_by”

然后我有一个像这样工作的函数:

def checkout(title, user):
    con = get_connection_from_db()
    with con:
        checked_out_by = get_checked_out_by(title)
        if checked_out_by == '': # If NOT checked out:
            checkout(title, user)
            print user, "checked out", title
        elif checked_out_by == 'user':
            print user, "already got it"
        else:
            print user, "can't check it out because", checked_out_by, "has it!"

所以 checkout() 函数首先验证这本书没有被借出,如果是,就去借出这本书。请注意,我正在使用推荐的“with con:”技巧来确保一切都是事务性的、快乐的和合作的。

但是,我运行了一堆并发测试并发现了问题。具体来说,当我同时运行以下两个调用时:

checkout('foo', 'steve')
checkout('foo', 'tim')

输出表明它不能正常工作。我希望看到以下两种可能的输出之一:

steve checked out foo
tim can't check it out because steve has it!

或者:

tim checked out foo
steve can't check it out because tim has it!

但偶尔,我会得到这样的输出:

tim checked out foo
steve checked out foo

我认为“with con:”技巧可以确保我的数据库调用捆绑在一起。有人可以向我解释我是否/如何弄错了吗?如果是这样,有没有办法让它发挥作用?

最佳答案

'with con' 不是这里想要的。 (或者这个线程锁定垃圾)

要获得特定时期的独占访问权(不仅仅是在进行单个查询/交易时),您需要这样做;

con = sqlite3.connect()
con.isolation_level = 'EXCLUSIVE'
con.execute('BEGIN EXCLUSIVE')
#exclusive access starts here. Nothing else can r/w the db, do your magic here.
con.commit()
con.close()

希望这能让某人免于我刚刚经历的搜索/实验!

请记住,在您运行 begin exclusive 之前它不是独占的,并且它将保持独占状态直到您关闭(或运行 commit,我认为)。如果您不确定,可以随时使用 python 解释器/CL sqlite3 应用程序进行测试。

关于sqlite - 在 Python 中锁定一个 sqlite3 数据库(重新要求澄清),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9070369/

相关文章:

angularjs - 选择Angular 2 + Electron应用程序的数据库

android - 计算 SQLITE 中单条记录的百分比

android - 如何更新 SQLite 数据库而不丢失所有现有数据?

python-3.x - sqlite3 错误 : You did not supply a value for binding 1

mysql - Ruby on Rails SQL "SELECT"需要很长时间

qt - 使用 sqlite3 驱动程序在 QSqlQuery 中使用多个 sql 语句

java - 为什么我的 Android 应用程序会关闭?

android - SQLiteOpenHelper,什么时候调用onCreate

python - 将表单字段插入数据库(Bottle、sqlite)

ios - 将大型CSV文件加载到核心数据中最快的方法是什么