在以下代码中,如果表中存在以下行,我将尝试向TransferRequest
表添加新行:
1- partnerId
列的值与我的预期相同
2-并且此行的状态现在为open
并且在插入后,我想将过滤后的行的状态更改为booked
partner = db.session.query(TransferRequest).filter(TransferRequest.id == partner_id).one()
if partner.status == RequestStatus.open.value:
request = TransferRequest()
#set values
db.session.add(request)
db.session.commit()
db.session.query(TransferRequest). \
filter(TransferRequest.id == partner_id). \
update({"status": RequestStatus.booked.value,
"partnerId": request.id})
db.session.commit()
return "success"
else:
return "failure"
这里的问题是,当我查询具有特定ID的项目并检查其状态时,在达到if
条件后,其他人可能会将行的状态从open
更改为booked
。在这种情况下,我不能插入行,插入后也不能执行update
命令。
我正在寻找一种可以在事务中执行所有这3个查询的方法,以便所有数据情况从第一条语句到结束语句都锁定。 (或者当然可以解决此问题的任何其他解决方案)
答案 0 :(得分:1)
我认为您代码中的主要问题是两次使用commit()。它将所有内容提交到数据库(作为事务),然后释放基础的事务锁。第二件事是,我还应该将with_for_update()添加到您的选择查询中,以锁定特定的行。完成一次提交,以保留您的更改并释放锁。一个例子可能是:
session = sessionmaker(bind=engine, autocommit=False)
partner = session.query(TransferRequest).with_for_update().filter(TransferRequest.id == partner_id).one()
if partner.status == RequestStatus.open.value:
request = TransferRequest()
#set values
session.add(request)
session.flush()
session.query(TransferRequest). \
filter(TransferRequest.id == partner_id). \
update({"status": RequestStatus.booked.value,
"partnerId": request.id})
session.commit()
return "success"
else:
return "failure"