SqlAlchemy ORM并发更新

时间:2015-10-07 11:11:03

标签: mysql sql transactions sqlalchemy transaction-isolation

我试图了解如何防止并发更新破坏我的应用程序。想象一下以下示例

Bob retrieves Post#1
Alice retrieves Post#1
Bob modifies and saves Post#1
Alice modifies and saves Post#1

现在Bobs的改变被覆盖了,因为Alice从来没有看到Bob改变了什么。这是Web应用程序中非常常见的问题,因为许多用户可能同时处理相同的数据。

此问题不仅限于上述简单案例。在提交事务之前,Bob可能会触摸几个数据库表。

那么如何防止这种情况?我能想到的一件事就是在行上使用一些哈希值。每次更新Post时,它都会获得一个新的uuid4。因此,当Alice试图修改它时,她需要首先发送她在阅读帖子时得到的哈希值:

GET /posts/1
response: {
    'text': 'Old post',
    '_hash': 'cef999ea-cffd-4ef8-b219-1ee905bbdbea'
}
POST /posts/1
{
    'text': 'New text, that I just wrote',
    '_hash': 'cef999ea-cffd-4ef8-b219-1ee905bbdbea'
}

现在,如果哈希与当前存储的哈希相同,应用程序应该只有一些方法来更新数据库行

UPDATE table SET (...) WHERE pk=1 AND _hash='cef999ea-cffd-4ef8-b219-1ee905bbdbea'

在这种情况下,Alice会收到错误,因为她想要更新的行不存在,因为Bob的更新改变了哈希。然后,应用程序层将能够帮助Alice整合两个更新(她和bob)。

这可能与sql炼金术orm有关吗?我假设当我提交事务时,它将更新行WHERE pk=1。我怎么能让它也使用哈希?

这种方法可行吗?如果动作触及许多表,则需要检查和处理大量哈希,这可能会非常混乱。我可以使用哪些其他解决方案?数据库行锁定有很多陷阱,很难逃脱。

0 个答案:

没有答案