我正在尝试执行以下操作:
给出一个数字和一个id,我想:
检查表A中是否存在该号码。
它需要在一个事务中完成,如果两个并发连接使用相同的值,hit_number应该只增加一个(所以我需要一些隔离)。
我想出了一个解决方案(在这个例子中我使用的是sqlite和python),但我不确定它是否足够好:
类似
con = sqlite3.connect(":memory:", isolation_level="EXCLUSIVE")
con.execute("create table A (num integer primary key);")
con.execute("create table B (user_id integer primary key, hit_number integer);")
# ... fill it with something
def hit(v, id, con):
try:
with con:
con.execute("INSERT INTO A VALUES (?);" +
"UPDATE B SET hit_number=hit_number+1 WHERE user_id=(?);", (v, id))
except sqlite3.IntegrityError:
return False
return True
这笔交易会原子化吗?我在这里真的需要EXCLUSIVE还是较低的隔离级别会给出完全相同的行为?还有更好的方法吗?
答案 0 :(得分:4)
仅使用.execute()
方法一次执行一个语句。在一个事务中,从来没有必要像这样在一个调用中执行两个语句;完整性错误异常将引发和中止事务:
try:
with con:
con.execute("INSERT INTO A VALUES (?);", (v,))
con.execute("UPDATE B SET hit_number=hit_number+1 WHERE user_id=(?);", (id,)
except sqlite3.IntegrityError:
return False
return True