我发现这个问题的答案有问题、混乱且不完整,所以我会努力做得更好。
Q1:我们如何确保写入用户可以在其他用户使用数据时更改表数据?读取用户是否在表上放置锁定?写入用户是否必须在表上放置锁定?Access是否为我们执行此操作,还是我们必须明确编写代码?
没有人真正完整地回答了这个问题。在Access选项中设置锁定的信息与读取锁定和写入锁定无关。 无锁定、所有记录和编辑记录是您为写入设置默认记录锁定的方式。
- 无锁定意味着您正在使用乐观锁定,这意味着您允许多个用户编辑记录,然后在事后通知他们记录是否已更改。乐观锁定是您应该从中开始的,因为它不需要编写代码即可实现,并且对于小型用户群体几乎永远不会引起问题。
- 所有记录意味着任何时候启动编辑时整个表都被锁定。
- 编辑记录意味着锁定的记录较少,但是是否是单个记录或多个记录取决于您的数据库是否设置为使用记录级锁定(首次添加于Jet 4)或页面级锁定。坦白地说,我从来没有认为设置记录级锁定值得麻烦,因为乐观锁定可以解决大部分问题。
人们可能认为您想使用记录级悲观锁定,但事实是,在绝大多数应用程序中,几乎从不会有两个用户编辑同一条记录。现在,显然,某些类型的应用程序可能是例外,但如果我遇到这样的应用程序,我可能会尝试通过重新设计模式将其消除,以使两个用户很少编辑相同的记录(通常通过转向某种事务性编辑来实现,其中通过添加记录而不是编辑现有数据进行更改)。
现在,针对您的实际问题,有许多方法可以限制某些用户只能读取并授予其他用户写入权限。Jet用户级安全性旨在实现此目的,并且在任何有意义的定义下都可以正常工作。通常情况下,只要您使用Jet/ACE数据存储,您将获得的最佳安全性就是Jet ULS提供的安全性。它是可破解的,但是您的用户如果突破了它,就会犯一个可以被解雇的罪行,所以它可能足够了。
我建议不要使用Jet ULS,而是在设计数据编辑表单时检查用户的Windows登录,并根据需要让表单只读或可写,以便让用户获得相应的访问权限。是否要在数据表中记录组成员身份,或者维护Windows安全组来实现这个目的,取决于您自己。您也可以使用Jet工作组文件来处理它,并为写入用户提供不同的system.mdw文件。只读用户会透明地以管理员身份登录,而以管理员身份登录的用户将只被授予只读访问权限。写用户将使用其他用户名(在您为启动应用程序提供的快捷方式中透明地提供,不提供密码),并用于设置表单为只读或可写。
如果使用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等。
问题3:我们能在使用中处理表单、查询等吗?我们如何“编程”而不妨碍用户?
这是其中一个已经得到很好解决的问题。所有多用户或复制的Access应用程序都应该进行分割,大多数单用户应用程序也应该进行分割。这是良好的设计,也使应用程序更稳定,因为只有数据表才会被多个用户同时打开。
问题4:MS Access中哪些设置会影响处理方式?
“事情?” 什么事?
问题5:我们的背景主要是Oracle,在处理多个用户方面,Access与Oracle有何不同?在Access中是否存在“隔离级别”?
我不知道Oracle的任何具体信息(即使他们想要,我的客户也负担不起它),但要求比较Access和Oracle表明某个地方存在基本的误解。
Access是一个应用程序开发工具。
Oracle是一款工业级数据库服务器。
苹果和橙子。
现在,当然,Access附带默认数据库引擎,最初称为Jet,现在已修订并更名为ACE,但在许多级别上,Access开发平台可以完全与默认数据库引擎Jet/ACE分离。
在这种情况下,您选择使用Jet/ACE后端,对于小用户群体(即少于25人)来说可能会非常好。当只有少数并发用户具有写入权限时,Jet/ACE也可以支持50或100个用户。虽然Jet/ACE中的255个用户限制包括只读和写用户,但真正控制您可以支持多少并发用户的是写用户的数量,在您的情况下,您拥有大多数只读用户的应用程序,因此应该很容易设计一个没有后端问题的好应用程序。
基本上,我认为您的Oracle背景可能会导致您误解如何在Access中开发,其中预期的方法是将表单绑定到记录源,而无需编写代码即可更新。现在,出于效率考虑,最好将表单绑定到记录子集,而不是整个表格,但即使在数据编辑表格的记录源后面有整个表格,只要您的数据表被有效地索引,Access 在编辑Jet/ACE表格方面也会相当高效(关于拉动整个表格跨越线路的旧神话仍然存在)。
记录锁定是您大多数情况下不必担心的事情之一,原因之一是由于绑定编辑,表单始终知道后端正在发生的事情(默认刷新间隔约为1秒)。也就是说,这不像一个网页,您检索数据的副本,然后将您的编辑在事务中发布回到与原始数据检索操作完全无关的服务器上。在像Access这样的绑定环境中,后端数据文件上的锁定文件始终会跟踪记录已打开以供编辑的事实。这可以防止用户的编辑覆盖其他人的编辑,因为Access知道状态并通知用户。这一切都发生在开发人员不需要编写任何代码的情况下,并且是绑定编辑模型的伟大优势之一(除了不必编写代码来发布编辑)。
对于所有有经验的数据库程序员熟悉其他平台的人第一次使用Access,我强烈建议像最终用户一样使用Access。尝试所有点和单击功能。运行表单和报告向导,并查看它们产生的结果。我不能保证所有这些都展示了良好的实践,但它们确实展示了Access旨在使用的默认假设。
如果您发现自己正在编写大量代码,那么您可能会错过Access的要点。