我在数据库中有一个表,用SQLAlchemy ORM模块映射(我有一个" scoped_session"变量) 我想要我的程序的多个实例(不仅是线程,也来自多个服务器)能够在同一个表上工作而不能处理相同的数据。 所以我编写了一本手册" row-lock"确保在这种方法中处理每一行的机制我使用" Full Lock"在桌子上,而我是" row-lock"它:
def instance:
s = scoped_session(sessionmaker(bind=engine)
engine.execute("LOCK TABLES my_data WRITE")
rows = s.query(Row_model).filter(Row_model.condition == 1).filter(Row_model.is_locked == 0).limit(10)
for row in rows:
row.is_locked = 1
row.lock_time = datetime.now()
s.commit()
engine.execute("UNLOCK TABLES")
for row in row:
manipulate_data(row)
row.is_locked = 0
s.commit()
for i in range(10):
t = threading.Thread(target=instance)
t.start()
问题是在运行某些实例时,多个线程正在崩溃并产生此错误(每个):
sqlalchemy.exc.DatabaseError :(由于Query-invoked而引发 自动冲洗;如果这次刷新,请考虑使用session.no_autoflush块 过早发生)(DatabaseError)1205(HY000):锁定等待 超时超时;尝试重新启动事务'更新my_daya SET row_var = 1}
渔获物在哪里?是什么让我的数据库表没有成功解锁?
感谢。
答案 0 :(得分:0)
锁是邪恶的。避免他们。发生错误时情况会非常糟糕。特别是当您将会话与原始SQL语句混合时,就像您一样。
作用域会话的优点在于它包装了一个数据库事务。此事务使对数据库的修改成为原子,并在出现问题时进行清理。
使用作用域会话如下:
with scoped_session(sessionmaker(bind=engine) as s:
<ORM actions using s>
重写代码以使其成为正确的事务可能是一些工作,但它是值得的! Sqlalchemy有技巧来帮助你。