我想在更新记录时阻止两个用户意外地互相覆盖。也就是说两个用户加载一个带有记录A的页面。用户1将记录更新为AB,用户2将其更新为AC。
我不只是想让最后一个命中数据库来覆盖。我需要一种机制来说明记录已经更新,因此你的记录无法保存。
现在我的两个想法是给记录加盖时间戳并检查。如果不匹配则不允许更新。第二种方法是每次执行更新时GUID记录,检查GUID以及它是否不匹配不更新。
这些方法中的任何一种都是有效的,如果是的话,这是最好的。如果没有,你有什么建议。这是在C#中,如果它有所作为
由于
答案 0 :(得分:11)
您提到的两种方法实际上是等效的 - 无论哪种方式,您都可以有效地获得“结账时记录”的唯一标识符。我没有任何关于哪个更好的特定视图,尽管时间戳显然可以为您提供有关记录 有效时的数据的额外好处。
另一种方法是记住以前的值是什么,只有在匹配时才允许更新 - 如果用户A开始编辑记录,那么用户B进入并更改某些内容,然后将其更改回来,用户A的编辑仍然有效。
这些技术的术语是乐观锁定(或optimistic concurrency control)。
答案 1 :(得分:5)
实际上有第三种方法。要进行更新,请发出以下格式的更新声明:
UPDATE table SET update_field = new_value
WHERE db_pk = my_pk // assume primary key immutable
AND update_field = original_field_value
其中original_field_value是尝试更新之前的字段值。如果其他人修改了update_field
,则此更新将失败,除非他们已将其更改为您拥有的相同值。
答案 2 :(得分:4)
您正在描述乐观锁定,这是一种有效且有用的技术。
答案 3 :(得分:2)
任何一种方法都适用于检查。
至于哪个是最好的,你必须查看你的应用程序的大小以及实现每个应用程序需要多长时间。因此,如果偶尔会发生这种情况,那么我会寻求更快的解决方案并实施时间戳选项。
如果你想要更详细的谷歌并发 - 下面是一篇文章 - concirrency
答案 4 :(得分:1)
我正在使用第一个选项。更新每次更新的时间戳。所以在更新时我们检查时间戳的相等性。
答案 5 :(得分:0)
乐观和悲观锁定的术语是否响铃。这些是您所描述的问题的两种公认方法。听起来你在网络环境中工作。在这种情况下,前一个选项(乐观锁定)更合适。您已经开始描述通常如何实现这一点。通常使用时间戳或版本号来检查自检索记录以来记录是否已更新。另一件需要考虑的事情是让您的用户知道底层数据发生了变化,并可能让他们选择他们试图保存的内容和另一个用户保存的内容。这个选择实际上取决于业务规则是什么。