有关访问数据的问题
如果两个用户正在访问同一个数据库表,我们如何防止用户覆盖彼此的数据?
谢谢,
-尼姆什
解决方案
没有直接的方法可以做到这一点。我们可以使用事务来确保正确解决了更新问题(即我们没有得到部分更新),但是我们可能会丢失第一组更改,因为第二组更改将覆盖它们。
我们可能有两个选择:
- 在应用程序级别实现某种锁定机制(即,当某人开始编辑记录时,将某个标志放在某个位置,这将阻止另一个用户执行此操作)
- 实现版本控制,以便每次有人将其写入数据库时都会创建一条新记录。这样,两组数据都将存储在数据库中,并且我们可以在应用程序中使用逻辑将它们合并或者选择所需的一组数据
请查看此讨论,以回顾一下应用程序中数据库锁定的不同策略或者技术。
好吧,这取决于。在编辑表格时,这不像在MSWord或者其他工具中打开文件一样。
我们正在发出专门一次添加或者更改一行或者一组行的命令,因此,除非两个人都在编辑同一行,否则两个用户的更改都将保留。
还可以在执行操作时(或者在事务内)隐式锁定表,或者如果我们确切知道要防止编辑的内容,则可以显式锁定表。大多数数据库提供"行级锁定",这意味着不需要为每个操作锁定整个表。
当我们开始考虑事务和MVCC时,它会变得更加复杂。如果我们让我们进一步了解我们感兴趣的具体情况,我们可以为我们提供更多具体的帮助。
我遇到的最聪明的方法是使用一个名为last_actv_dtm
的添加字段,该字段在有人修改记录时进行更新。假设应用程序首先查询记录,那么对于要修改的记录,我们应该具有" last_actv_dtm"。
使用此SQL执行更新。
UPDATE tab1 SET col1 = ? , col2 = ? , last_actv_dtm = GETDATE() WHERE pkcol = rec.pkcol AND last_actv_dtm = rec.last_actv_dtm;
如果自应用程序选择记录以来未对其进行修改,则只会更新该行。
这是一个大问题,没有简单的答案。关键在于我们如何愿意在另一个用户使用它时阻止一个用户,以及如何防止死锁和糟糕的性能发生。另外,我们是否要阻止一个用户更新另一个用户的同一行,或者只是更新同一表中的另一行?如果用户A更新该行,然后用户B尝试更新该行,它应该失败,更新还是静默忽略它?一旦进一步定义了问题,就可以决定是否需要表级锁,行级锁,事务,以及是否需要各种级别的事务隔离。
一些数据库服务器支持类似以下的构造:
SELECT column FROM table WHERE something = 'whatever' FOR UPDATE;
它将锁定选择返回的所有行,直到发出COMMIT或者ROLLBACK为止。
MySQL(InnoDB)和Oracle是两个支持此功能的数据库。