私は次のことをしようとしています:
- テーブルAには、一意の番号で構成される列が1つだけあります(連続していない)
- テーブルBには、id(一意の非連続整数)とhit_number(正の整数)の2つの列があります。
番号とIDを指定して、次のことを行います。
番号が表Aにあるかどうかを確認します。
- それが存在する場合は、何もしないでください。私に知らせてください
- 存在しない場合は、テーブルAに挿入し、このIDに対応するテーブルBのhit_number列をインクリメントして、お知らせください。
これは単一のトランザクションで実行する必要があり、同じ値で2つの同時接続を行う場合は、hit_numberを1つだけ増やす必要があります(したがって、ある程度の分離が必要だと思います)。
私は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が必要ですか、それとも分離レベルを低くするとまったく同じ動作になりますか?もっと良い方法はありますか?