26

我们正在考虑为多个用户“增长”一个带有一些表、表单和查询的小型 MS-Access 数据库。(使用不同的后端是另一种,但更长期的选择,遗憾的是目前不可接受。)
大多数用户将是只读的,但会有一些(目前是一两个)用户必须能够进行更改(而只读用户也在使用数据库)。我们不太关心安全方面,而是更关心以下一些问题:

  • 我们如何确保写入用户可以在其他用户使用数据时更改表数据?读用户是否在表上加了锁?写用户是否必须在表上加锁?Access 是否为我们执行此操作,还是我们必须明确对此进行编码?
  • 我们应该注意的“MS Access 事务”是否存在任何常见问题?
  • 我们可以在使用表单、查询等的同时处理它们吗?我们如何在不妨碍用户的情况下“编程”?
  • MS Access 中的哪些设置会影响处理方式?
  • 我们的背景主要是Oracle,Access在处理多用户方面有什么不同呢?Access中是否有“隔离级别”之类的东西?

任何有用的文章的提示或指针将不胜感激。

4

7 回答 7

52

我发现这个问题的答案是有问题的、令人困惑的和不完整的,所以我会努力做得更好。

Q1:我们如何确保写用户可以在其他用户使用数据时更改表数据?读用户是否在表上加了锁?写用户是否必须在表上加锁?Access 是否为我们执行此操作,还是我们必须明确对此进行编码?

没有人真正以任何完整的方式回答过这个问题。在访问选项中设置锁的信息与读与写锁定无关。No Locks vs. All Records vs. Edited Record 是您为 WRITES 设置默认记录锁定的方式。

  • 无锁意味着您正在使用 OPTIMISTIC 锁定,这意味着您允许多个用户编辑记录,然后在他们启动自己的编辑后记录是否发生更改后通知他们。乐观锁定是您应该开始的,因为它不需要编码来实现它,而且对于小用户群体来说,它几乎不会引起问题。

  • 所有记录意味着每次启动编辑时都会锁定整个表。

  • Edited Record 意味着更少的记录被锁定,但它是单个记录还是多个记录取决于您的数据库是设置为使用记录级锁定(在 Jet 4 中首次添加)还是页面级锁定。坦率地说,我从不认为设置记录级锁定值得麻烦,因为乐观锁定可以解决大部分问题。

有人可能会认为您想使用记录级悲观锁定,但事实是,在绝大多数应用程序中,两个用户几乎从不编辑同一条记录。现在,显然,某些类型的应用程序可能是例外,但如果我遇到这样的应用程序,我可能会尝试通过重新设计架构来设计它,这样两个用户编辑相同的应用程序就很罕见了记录(通常通过某种形式的事务编辑代替,通过添加记录而不是编辑现有数据进行更改)。

现在,对于您的实际问题,有多种方法可以完成将某些用户限制为只读并授予其他用户写入权限。Jet 用户级安全性就是为此目的而设计的,只要它对术语的任何有意义的定义都是“安全性”的,它就可以正常工作。一般来说,只要您使用 Jet/ACE 数据存储,您将获得的最佳安全性就是 Jet ULS 提供的安全性。是的,它是可破解的,但是您的用户会通过破坏它来犯下严重的罪行,所以它可能就足够了。

我倾向于根本不实施 Jet ULS,而只是构建数据编辑表单,以便他们检查用户的 Windows 登录并根据哪些用户应该获得哪些访问权限使表单只读或可写。是否要在数据表中记录组成员身份,或为此目的维护 Windows 安全组取决于您。您还可以使用 Jet 工作组文件来处理它,并为写入用户提供不同的 system.mdw 文件。只读用户将以 admin 身份登录,而以 admin 身份登录的用户仅被授予只读访问权限。写入用户将以其他用户名登录(显然,在您为启动应用程序提供的快捷方式中,不提供密码),这将用于将表单设置为读取或写入。

如果您使用 Jet ULS,它会变得非常麻烦。它涉及将所有表锁定为只读(或者甚至可能不是),然后使用 RWOP 查询来提供对数据的访问。在我 14 年的专业 Access 开发中,我只做过一个这样的应用程序。

总结一下我对您问题部分的回答:

我们如何确保写入用户可以在其他用户使用数据时更改表数据?

我建议在应用程序中执行此操作,根据用户登录将表单设置为在运行时只读/只读或可编辑。最简单的方法是将表单设置为只读,并在写入用户打开表单时更改为可编辑。

读用户是否在表上加了锁?

没有任何意义。Jet/ACE 确实有读锁,但它们的存在只是为了维护各个视图的状态,以及为用户刷新数据。它们不会锁定任何类型的写操作,尽管理论上跟踪它们的开销会减慢速度。担心是不够的。

写用户是否必须在表上加锁?

Access 与 Jet/ACE 结合使用会自动为您执行此操作,尤其是在您选择乐观锁定作为默认设置的情况下。这里的关键是Access应用程序是数据绑定的,因此一旦加载表单,记录就会有读锁,而一旦编辑记录,是否对其他用户进行写锁定取决于无论您使用的是乐观锁定还是悲观锁定。同样,这是 Access 以绑定表单中的默认行为为您处理的事情。在遇到问题之前,您无需担心任何问题。

Access 是否为我们执行此操作,还是我们必须明确对此进行编码?

基本上,除了在运行时设置可编辑性(根据谁具有写访问权限),如果您使用乐观锁定,则不需要编码。使用悲观锁定,您不必编写代码,但您几乎总是需要编写代码,因为您不能让用户停留在默认行为和错误消息中。

Q2:“MS Access 事务”有什么常见问题需要注意吗?

Jet/ACE 支持提交/回滚事务,但我不清楚这是否是您在这个问题中的意思。通常,除了维护原子性(例如,在创建发票或进行涉及多个表的任何更新时)之外,我不使用事务。它以您期望的方式工作,但对于 Access 应用程序中的绝大多数操作并不是真正必需的。

也许这里的一个问题(特别是根据第一个问题)是您可能不太了解 Access 是为创建具有绑定到表单的数据的应用程序而设计的。“事务”对于未绑定和无状态的应用程序(例如,基于浏览器)来说是一个非常重要的主题,但对于数据绑定的应用程序,编辑和保存都是透明的。

对于某些类型的操作,这可能是有问题的,有时在 Access 中使用未绑定的表单编辑数据是合适的。但根据我的经验,这种情况很少见。并不是说我不使用未绑定的表单——我将它们中的很多用于对话框等——只是我的应用程序不使用未绑定的表单编辑数据表。几乎没有例外,我所有的应用程序都使用绑定表单编辑数据。

现在,未绑定的表单实际上在 Access 中很容易实现(特别是如果您将编辑控件命名为与基础字段相同的名称),但是使用未绑定的数据编辑表单确实缺少使用 Access 的要点,即绑定是一切都为你完成。未绑定的主要缺点是您会丢失所有记录级别的表单事件,例如 OnInsert、BeforeUpdate 等。

Q3。我们可以在使用表单、查询等的同时处理它们吗?我们如何在不妨碍用户的情况下“编程”?

这是已经得到很好解决的问题之一。所有多用户或复制的 Access 应用程序都应拆分,大多数单用户应用程序也应拆分。这是一个很好的设计,也使应用程序更加稳定,因为只有数据表最终一次由多个用户打开。

Q4。MS Access 中的哪些设置会影响处理方式?

“事物?” 什么东西?

Q5。我们的背景主要是Oracle,Access在处理多用户方面有什么不同呢?Access中是否有“隔离级别”之类的东西?

我对甲骨文一无所知(即使我的客户愿意,我的客户也买不起),但是要求比较 Access 和甲骨文暴露了一个基本的误解。

Access 是一种应用程序开发工具。

Oracle 是工业级数据库服务器。

苹果和橙子。

当然,现在 Access 附带了一个默认数据库引擎,最初称为 Jet,现在经过修改和重命名为 ACE,但在许多级别上,Access 开发平台可以与默认数据库引擎 Jet/ACE 完全分离。

在这种情况下,您选择使用 Jet/ACE 后端,这对于小用户群(即 25 岁以下)可能会很好。Jet/ACE 也可以达到 50 或 100,特别是当只有少数同时的用户有写权限。虽然 Jet/ACE 中的 255 位用户限制包括只读用户和写入用户,但真正控制您可以支持多少并发用户的是写入用户的数量,在您的情况下,您的应用程序主要是读取- 仅限用户,因此设计一个后端没有问题的好应用程序应该不是很困难。

基本上,我认为您的 Oracle 背景可能会导致您误解如何在 Access 中进行开发,其中预期的方法是将您的表单绑定到无需编写代码即可更新的记录源。现在,为了提高效率,将表单绑定到记录子集而不是整个表是一个好主意,但是即使在数据编辑表单后面的记录源中有整个表,Access 在编辑 Jet/只要您的数据表被有效索引,ACE 表(关于将整个表拉过电线的古老神话仍然存在)。

记录锁定是您最不应该担心的事情,其中​​一个原因是由于绑定编辑,表单始终知道后端发生了什么(嗯,间隔大约秒间隔,默认刷新间隔)。也就是说,它不像一个网页,您可以在其中检索数据的副本,然后在与原始数据检索操作完全无关的事务中将您的编辑发布回服务器。在像 Access 这样的绑定环境中,后端数据文件上的锁定文件始终会跟踪有人打开记录以供编辑的事实。这可以防止用户的编辑踩到其他人的编辑,因为 Access 知道状态并通知用户。

对于所有第一次使用 Access 的熟悉其他平台的经验丰富的数据库程序员,我强烈建议像最终用户一样使用 Access。尝试所有的点击功能。运行表单和报告向导并检查它们产生的结果。我不能保证所有这些都展示了良好的做法,但它们肯定展示了 Access 预期使用方式背后的默认假设。

如果您发现自己编写了大量代码,那么您可能错过了 Access 的要点。

于 2009-11-06T00:33:07.857 回答
4

要做的第一件事(如果尚未完成)是将数据库拆分为前端(包含所有表单/报告等)和后端(包含所有数据)。第二件事是在前端设置版本控制。

我在很多数据库中这样做的方式是让用户运行一个小型“跳线”数据库来打开主数据库。该跳线执行以下操作

• 检查用户的 C 盘上是否有数据库

• 如果没有,则安装并运行

• 如果有,请检查他们拥有的版本

• 如果版本号不匹配,则复制最新版本

• 打开数据库

整个检查过程通常需要不到半秒的时间。使用此模型,您可以在单独的数据库上进行所有开发,然后当您准备“发布”时,您只需将新的 mde 放到网络共享上,下次用户打开跳线时,最新版本会被复制下来。

在多用户数据库中还有其他需要考虑的事情,可能值得检查常见错误,例如将表单绑定到整个表等

于 2009-11-04T08:34:40.850 回答
2

在数据写入期间,表或记录锁定在 Access 中可用。您可以通过工具 | 控制默认记录锁定。选项 | 高级选项卡:

  1. 没有锁
  2. 所有记录
  3. 编辑记录

您可以根据特定需要在表单的记录锁或 DAO/ADO 代码中进行设置。

如果您正确使用交易,交易应该不会成为问题。

最佳实践:将您的表格与所有其他代码分开。为每个用户提供自己的代码文件副本,然后在网络服务器上共享数据文件。处理代码的“测试”副本(以及测试数据文件的链接),然后分别更新用户的个人代码文件。如果您需要更改数据文件(添加表、列等),则必须让所有用户退出应用程序才能进行更改。

请参阅 Oracle 比较的其他答案。

于 2009-11-04T14:49:47.227 回答
2

我认为 Access 是您的最佳选择。但是您必须拆分数据库,请参阅: http ://accessblog.net/2005/07/how-to-split-database-into-be-and-fe.html

•我们如何确保写用户可以在其他用户使用数据时更改表数据?读用户是否在表上加了锁?写用户是否必须在表上加锁?Access 是否为我们执行此操作,还是我们必须明确对此进行编码?

除非您明确放置它们,否则没有读锁。只需使用“无锁”

•“MS Access 事务”是否存在我们应该注意的常见问题?

1-2个写用户应该不是问题

•我们可以在使用表单、查询等的同时处理它们吗?我们如何在不妨碍用户的情况下“编程”?

如果您拆分数据库 - 那么进行 FE 设计就没有问题了。

• MS Access 中的哪些设置会影响处理方式?

你是什​​么意思?

•我们的背景主要是Oracle,Access在处理多用户方面有什么不同?Access中是否有“隔离级别”之类的东西?

访问中没有隔离级别。顺便说一句,如果您有很多用户和大型数据库,您可以稍后将数据移动到 oracle 并保持访问前端。

于 2009-11-05T06:33:29.260 回答
0

构建数据存储在 RDBMS 中的客户端/服务器 Microsoft Access 应用程序的正确方法是使用链接表方法。这确保了 Microsoft Access 客户端应用程序和 RDBMS 数据之间的数据隔离和并发性得到维护,没有额外的和不必要的编程逻辑和代码,这使得维护更加困难,并增加了开发时间。

见:http ://claysql.blogspot.com/2014/08/normal-0-false-false-false-en-us-x-none.html

于 2014-08-11T21:10:39.713 回答
0

Access 是一个很棒的多用户数据库。它具有许多内置功能来处理多用户情况。事实上,它非常受欢迎,因为它是一个非常棒的多用户数据库。有多少用户可以同时使用数据库进行更新和编辑是有上限的——这取决于开发人员对访问的了解程度以及数据库的设计方式——从 20 个用户到大约 50 个用户不等。一些访问数据库可以构建为最多处理 50 个并发用户,而许多其他数据库可以处理 20 或 25 个并发用户更新数据库。这些数字已经在使用了几年或更长时间的数据库中观察到,并且在访问新闻组上已经讨论过很多次。

于 2009-11-05T06:22:02.620 回答
0

我发现在 Vista 中引入了 SMB2 协议来锁定访问数据库。可以通过以下注册表禁用它:

Windows 注册表编辑器版本 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters] "Smb2"=dword:00000000

于 2014-05-29T15:27:32.340 回答