SQLAlchemy 与显式锁定
我有多个进程可能会往数据库里插入重复的行。这些插入操作并不是很频繁(每小时几次),所以性能不是特别关键。
我尝试在插入之前先检查一下是否已经存在,比如这样:
#Assume we're inserting a camera object, that's a valid SQLAlchemy ORM object that inherits from declarative_base...
try:
stmt = exists().where(Camera.id == camera_id)
exists_result = session.query(Camera).with_lockmode("update").filter(stmt).first()
if exists_result is None:
session.add(Camera(...)) #Lots of parameters, just assume it works
session.commit()
except IntegrityError as e:
session.rollback()
我遇到的问题是,exist()
检查并不会锁定表格,因此可能会有多个进程同时尝试插入相同的对象。在这种情况下,一个进程成功插入了,而其他进程则会因为完整性错误(IntegrityError)而失败。虽然这样也能工作,但我觉得这并不“干净”。
我真的希望能有一种方法,在进行 exists()
检查之前先锁定 Camera 表。
1 个回答
11
也许这个对你会有帮助:
https://groups.google.com/forum/?fromgroups=#!topic/sqlalchemy/8WLhbsp2nls
你可以通过直接执行SQL语句来锁定表。我不太确定在Elixir中是怎样的,但在普通的SQLAlchemy中,大概是这样的:
conn = engine.connect() conn.execute("LOCK TABLES Pointer WRITE") #do stuff with conn conn.execute("UNLOCK TABLES")