我試圖做到以下幾點:SQL事務,插入,然後更新如果插入成功的是
- 表A中只有一列由獨特的數字(非連續)
- 表B有兩列,一個ID(獨特的非連續的整數),並假定一個編號和ID的hit_number(正整數)
,我想:
檢查數量在TA存在BLE A.
- 如果存在,則什麼也不做,只是讓我知道
- 如果它不存在,表A插入,增加表B中的hit_number列對應於此身份證,並讓我知道。
它需要在單個事務中完成,如果兩個併發連接要在同一個值中創建,hit_number只應該增加1(所以我需要一些隔離)。
,我想出了一個解決方案(在這個例子中,我使用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還是會降低隔離級別給出完全相同的行爲?有沒有更好的辦法?
氣味像非規範化的數據..在任何情況下,1)只使用兩個語句? 2)插入失敗不會阻止更新運行嗎?至於原子性,請參閱http://www.sqlite.org/lockingv3.html – 2013-03-25 21:00:18
如果插入成功並且服務器崩潰並且hit_number永遠不會增加會怎麼樣? – 2013-03-25 21:01:50
查看我發佈的鏈接。要麼使用自動提交(並且僅在數據庫操作完成時提交事務*)或不使用自動提交併且必須手動調用「提交」。 SQLite完全是ACID。無論如何,它似乎仍然是「」「。 – 2013-03-25 21:02:51