我认为您可以使用事务来解决您的问题。这是适当的 django 文档,这是一个示例。
如果您尝试让两个并发事务写入同一个 sqlite DB,看起来您会得到“OperationalError:database is locked”。您可能想要使用 Django ORM(请参阅链接),但这里有一个 hacky 示例来演示这个想法。
import sqlite3
# 2 connections, 2 cursors
con = sqlite3.connect('test.db', isolation_level=None)
con2 = sqlite3.connect('test.db', isolation_level=None)
cur = con.cursor()
cur2 = con2.cursor()
# create really simple table
try:
cur.execute("CREATE TABLE MOVIES(id INTEGER PRIMARY KEY, r1 INTEGER, r2 INTEGER)")
cur.execute("INSERT INTO MOVIES(id,r1, r2) VALUES (1,0,0)")
cur.execute("INSERT INTO MOVIES(id,r1, r2) VALUES (2,0,0)")
except:
pass
# awkward read/write split mid-transaction is purely for demonstration purposes..
def read(cursor):
cursor.execute("BEGIN IMMEDIATE TRANSACTION") # get write lock straight away
data = cursor.execute("SELECT * FROM MOVIES WHERE r1 == 0 OR r2 == 0")
return data.fetchall()
def write(cursor, movie_id, reviewer_column, new_reviewer_id):
cursor.execute("UPDATE MOVIES SET %s=%d WHERE id == %d AND %s ==0" % (
reviewer_column, new_reviewer_id, movie_id, reviewer_column))
cursor.execute("COMMIT")
# works fine
data1 = read(cur) # [(1, 0, 0), (2, 0, 0)]
write(cur, data1[0][0], "r1", 123)
# now we have concurrent access..
data1 = read(cur) # [(1, 123, 0), (2, 0, 0)]
data2 = read(cur2) # throws OperationalError: database is locked.
# the second thread should probably wait a bit before retrying.
# in the mean time..
write(cur, data1[0][0], "r2", 456) #works
# now it's safe for the second thread to retry
data2 = read(cur2) # [(2, 0, 0)]
write(cur2, data2[0][0], "r1", 457) #works
以上之后的数据:
# MOVIES
# id | r1 | r2
# 1 | 123 | 456
# 2 | 457 | 0
它会保护你避免在你的数据库中胡说八道,但是立即写锁是一种稍微粗略的到达那里的方式。