当2个用户尝试连接时,谁获得访问的优先级

本文关键字:访问 优先级 用户 2个 连接 | 更新日期: 2023-09-27 18:04:38

如果2个用户连接到Access并运行查询,检查最后一个数字,增加这个数字并插入一条记录到数据库

谁有优先权?

为什么我看到两个相同数字的重复记录?

当2个用户尝试连接时,谁获得访问的优先级

这是一个并发性问题:

用户A和B都从数据库中读取当前值。然后A在客户端增加它并将其写回数据库,但B已经读取了值并且不知道增加的值。与之前的A一样,B也增加了该值并将其写回来,用相同的数字覆盖A的更改。

这种唯一数字生成是不安全的。您应该让数据库通过使用自动增量值来执行增量。

或者,您可以使用以下结构:

  • 创建一个额外的ID表
  • 创建一个存储过程,您可以在其中
    • 锁访问ID表
    • 读取当前值
    • 增加并写回
    • 解锁访问
    • 返回递增的值
创建ID表可以防止锁定数据表。

他们都没有获得"优先权"。当你讨论非原子操作时,这不再是一个有用的术语。这里有一个例子可以说明这个问题。

脚本如下:

  • 从数据库读取值
  • 增加1.
  • 向数据库写入新值。

这在一次只有一个人使用数据库时有效。当不止一个人这样做的时候,事情就行不通了。下面是现在的情况:

  • DB中的原始值为"100"。
  • 客户端A读取"100"。
  • 客户端A将"100"在本地递增到"101",但还没有写入。
  • 客户端B读取"100"。
  • Client B将"100"在本地递增到"101",但还没有写入。
  • 客户端A写入"101"。
  • 客户端B写入"101".

这被称为竞争条件,它的发生是因为您没有使用事务。对于事务,下面是可能发生的情况:

  • DB中的原始值为"100"。
  • 客户端A在这个值上开始一个事务。
  • 客户端A读取"100"。
  • 客户端A将"100"在本地递增到"101",但还没有写入。
  • 客户端B试图开始一个事务,但是已经有一个挂起的事务,所以它还不能开始。
  • 客户端A写入"101"。
  • 客户端A关闭事务,并实际写入值。
  • 客户端B在此值上开始事务。
  • 客户端B读取"101"。
  • 客户端B将"101"在本地递增到"102",但还没有写入。
  • 客户端B写入"102".
  • 客户端B关闭事务,并实际写入值。

好吧,从问题中的最后一个问题开始,您看到两个记录具有重复数字的原因是因为您在模式/数据库/表设计中允许这样做。从在数据库中添加约束和关系开始,您的场景将抛出错误,而您可以使用乐观并发从客户端开始,并且/或继续在数据库端生成唯一键和/或使用事务等。

这是一个Access常见问题。如果你用谷歌搜索"访问多用户自定义计数器",你会得到一大堆解决方案。

它们通常基于使用一个表来保存"种子"值,该值被独家编辑,因此一次只有一个用户可以更改该种子值。可能还有其他使用Jet/ACE事务的方法,但是这种方法要简单得多。

请注意,来自MS的三个解决方案中的两个使用ADO,这在Access中是不可取的,但在Access外部可能是合适的。