这很长,所以这里是简短的答案:
不要设置其中任何一个。这两个选项的默认设置可能是正确的。第一个,事务提交模式,控制 Jet 的隐式事务,并应用于显式事务之外,并设置为 YES(异步)。第二个控制 Jet 在显式事务期间如何与其临时数据库交互并设置为 NO(同步)。我想不出你想在这里覆盖默认值的情况。但是,您可能需要明确设置它们,以防万一您在 Jet 数据库引擎设置已更改默认值的环境中运行。
现在,详细的解释:
我翻阅了很多与 Jet 相关的资源,看看是否能找出这里的情况。这两个 OLEDB 常量似乎映射到顶级 DAO DBEngine 对象的 SetOptionEnum 的这两个成员(详细信息 here 对于那些没有可用的 Access 帮助文件的人):
dbImplicitCommitSync
dbUserCommitSync
这些选项用于在运行时为任何特定连接覆盖 Jet 数据库引擎的默认注册表设置,或用于永久更改注册表中存储的设置。如果您在注册表中查找 HLKM\Software\Microsoft\Jet\X.X\,您会发现在您使用的 Jet 版本的键下有键,其中两个是:
ImplicitCommitSync
UserCommitSync
Jet 3.5 数据库引擎程序员指南定义了这些:
现在,这只是对您已经说过的内容的重述。令人沮丧的是,第一个默认值为 NO,而第二个默认值为 YES。如果他们真的控制着同样的东西,你会期望他们有同样的价值,否则冲突的价值就会成为一个问题。
但实际上关键在于名称,它反映了 Jet 在事务内部和外部如何提交数据写入的历史。在 Jet 3.0 之前,Jet 默认在显式事务之外进行同步更新,但从 Jet 3.0 开始,引入了隐式事务,并且默认使用(在 Jet 3.5 中有警告——见下文)。因此,这两个选项之一适用于事务外部提交 (dbImplicitCommitSync),另一个适用于事务内部提交 (dbUserCommitSync)。我终于在 Jet Database Engine Programmer's Guide (p. 607-8) 中找到了对这些的详细解释:
用户提交同步
UserCommitSynch 设置确定
是否将更改作为
显式事务...写入
同步模式下的数据库或
异步模式。默认值...是 Yes,它指定
异步模式。它不是
建议您更改此值
因为在同步模式下,有
不保证信息已被
在您的代码之前写入磁盘
继续执行下一个命令。
隐式提交同步
默认情况下,当
执行添加的操作,
删除或更新外部记录
显式事务,Microsoft Jet
自动执行内部
称为隐式的事务
暂时保存的交易
内存缓存中的数据,然后
稍后将数据作为一个块写入
磁盘。 ImplicitCommitSync 设置
确定是否由
使用隐式事务是
同步写入数据库
模式或异步模式。默认
值...是否,它指定
这些更改被写入
数据库处于异步模式;这
提供最佳性能。如果你
希望隐式交易成为
同步写入数据库
模式,将值...更改为是。如果
你改变价值......你得到
类似于 Microsoft Jet 的行为
版本 2.x 及更早版本,当您
没有使用显式事务。
但是,这样做也会损害
性能相当,所以它不是
建议您更改值
这个设置。
注意:不再需要使用
显式交易以改善
Microsoft Jet 的性能。一种
使用 Microsoft 的数据库应用程序
Jet 3.5 应该使用显式
仅在以下情况下进行交易
可能需要回滚
变化。 Micosoft Jet 现在可以
自动执行隐式
交易以提高性能
无论何时添加、删除或更改
记录。然而,隐含的
SQL DML 语句的事务
在 Microsoft Jet 中被删除
3.5...参见“删除 SQL DML 语句的隐式事务”
本章后面。
那个部分:
删除 SQL DML 语句的隐式事务
即使在微软工作
Jet 3.0 消除交易
为了获得更好的性能,
仍然放置 SQL DML 语句
在隐式交易中。在
Microsoft Jet 3.5,SQL DML 语句
不被置于隐含的
交易。这实质上
提高运行 SQL 时的性能
影响许多的 DML 语句
数据记录。
虽然这一变化提供了一个
显着的性能提升,
它还引入了对
SQL DML 语句的行为。什么时候
使用 Microsoft Jet 3.0 及更早版本
使用隐式的版本
SQL DML 语句的事务,
SQL DML 语句回滚(如果有)
声明的一部分不是
完全的。使用 Microsoft Jet 时
3.5、可能有SQL DML提交的一些记录
声明,而其他人则没有。一个
这方面的例子是当
已超出 Microsoft Jet 缓存。这
缓存中的数据写入磁盘
下一组记录是
修改并放入缓存中。
因此,如果连接是
终止,有可能是一些
的记录已保存到磁盘,但
其他人没有。这是一样的
使用 DAO 循环例程的行为
在没有明确的情况下更新数据
Microsoft Jet 3.0 中的事务。如果
你想避免这种行为,你
需要添加显式事务
围绕 SQL DML 语句来定义
一套工作,你必须牺牲
性能提升。
困惑了吗?我当然是。
在我看来,关键点似乎是 dbUserCommitSync 似乎控制 Jet 写入用于暂存 EXPLICIT 事务的 TEMPORARY 数据库的方式,而 dbImplicitCommitSync 与 Jet 在显式事务之外使用其隐式事务的位置有关。换句话说,dbUserCommitSync 控制引擎在 BeginTrans/CommitTrans 循环内的行为,而 dbImplicitCommitSync 控制 Jet 在显式事务之外的异步/同步行为。
现在,关于“删除隐式事务”部分:我的阅读是,当您在事务外循环记录集时,隐式事务适用于更新,但不再适用于事务外的 SQL UPDATE 语句.按理说,提高逐行更新性能的优化会很好,并且实际上对 SQL 批量更新没有太大帮助,这已经非常快了(相对而言)。
还要注意,这两种方式都可以做到这一点,这使得 DoCmd.RunSQL 能够进行不完整的更新。也就是说,如果使用 DoCmd.RunSQL 执行,将因 CurrentDB.Execute strSQL dbFailOnError 失败的 SQL 命令可以运行到完成。如果关闭 DoCmd.SetWarnings,则不会收到错误报告,也没有机会回滚到初始状态(或者,如果您被告知错误并决定提交,无论如何)。
所以,我认为通过 Access UI 执行的 SQL 默认包装在事务中(这就是您获得确认提示的方式),但是如果您关闭提示并且出现错误,您会得到应用了不完整的更新。这与 DBEngine 设置无关——这与 Access UI 执行 SQL 的方式有关(并且可以选择关闭/打开它)。
这与 DAO 中的更新形成对比,从 Jet 3.0 开始,这些更新都被包装在隐式事务中,但从 Jet 3.5 开始,只有顺序更新被包装在隐式事务中——批处理 SQL 命令 (INSERT/UPDATE/DELETE)不是。
至少,这是我的阅读。
因此,关于您实际问题中的问题,在设置您的 OLEDB 连接时,您需要根据您的操作为该连接设置 Jet DBEngine 的选项。在我看来,默认的 Jet DBEngine 设置是正确的,不应更改——您希望使用隐式事务进行编辑,您正在遍历记录集并一次更新一行(在显式事务之外) .另一方面,您可以将整个事物包装在事务中并获得相同的结果,所以实际上,这仅适用于您正在遍历记录集和更新并且没有使用显式事务的情况,并且默认设置似乎对我来说完全正确。
另一个设置,UserCommitSync,在我看来,您肯定也不想管它,因为在我看来,它适用于 Jet 在显式事务期间与其临时数据库交互的方式。将其设置为异步在我看来是非常危险的,因为您在提交数据时基本上不知道操作的状态。