【问题标题】:What's the difference between Jet OLEDB:Transaction Commit Mode and Jet OLEDB:User Commit Sync?Jet OLEDB:Transaction Commit Mode 和 Jet OLEDB:User Commit Sync 有什么区别?
【发布时间】:2010-12-30 13:32:11
【问题描述】:

虽然 Jet/OLE DB 参数都是相对的 well documented 我无法理解这两个连接参数之间的区别:

第一个:

Jet OLEDB:事务提交模式 (DBPROP_JETOLEDB_TXNCOMMITMODE)

指示 Jet 是否将数据写入 磁盘同步或异步 提交事务时。

第二个:

Jet OLEDB:用户提交同步 (DBPROP_JETOLEDB_USERCOMMITSYNC)

表示更改是否 交易中进行的交易被写入 同步或异步模式。

有什么区别?什么时候用哪个?

【问题讨论】:

  • 你看过我的回答了吗?有问题吗?
  • 我已经 AFK 一个星期了(医院)。你的回答当然很棒!

标签: oledb jet


【解决方案1】:

这很长,所以这里是简短的答案:

不要设置其中任何一个。这两个选项的默认设置可能是正确的。第一个,事务提交模式,控制 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 数据库引擎程序员指南定义了这些:

  • ImplicitCommitSync:Yes 值表示 Microsoft Jet 将等待提交完成。 Yes 以外的值表示 Microsoft Jet 将异步执行提交。

  • UserCommitSync:当设置值为“是”时,Microsoft Jet 将等待提交完成。任何其他值意味着 Microsoft Jet 将异步执行提交。

现在,这只是对您已经说过的内容的重述。令人沮丧的是,第一个默认值为 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 在显式事务期间与其临时数据库交互的方式。将其设置为异步在我看来是非常危险的,因为您在提交数据时基本上不知道操作的状态。

【讨论】:

  • 我很想知道是否有人读过这篇文章。我花了很多时间在上面,而且,我认为,肯定地回答了它。对原始提问者的某种回应似乎是合适的。
  • 非常感谢您的精彩回答!我想指出,它实际上似乎是关于DBPROP_JETOLEDB_IMPLICITCOMMITSYNC,而不是关于DBPROP_JETOLEDB_TXNCOMMITMODE(OP 要求的)。
【解决方案2】:

您会认为USERCOMMITSYNC=YES 是同步提交的选项。这就是造成混乱的原因。

我花了很长时间在谷歌上搜索这个主题,因为我发现旧的vb6 应用程序的行为与.net oledb/jet4 的行为不同

现在我真的应该用我阅读的实际页面的链接来备份我要说的内容,但我现在找不到这些页面。

无论如何,我在浏览 MSDN 网站时发现了一个页面,该页面描述了 Jet3 中的“按设计”错误,它转换了 USERCOMMITSYNC 的功能,这意味着 NO 的值会获得同步提交。

因此,MS 将默认设置为 NO,我们默认获得同步提交。正如上面大卫芬顿所描述的那样。我们都接受的行为。

但是,该文件接着解释说oledb/Jet4 中的行为已经改变。基本上,MS 修复了他们的错误,现在USERCOMMITSYNC=YES 的设置就如它所说的那样。

但他们是否更改了默认设置?我认为不是因为现在我的显式事务使用oledb/jet4 在.Net 应用程序中同步提交。

【讨论】:

    猜你喜欢
    • 2015-07-14
    • 2011-05-11
    • 2018-03-27
    • 2020-04-03
    • 2021-02-26
    • 2011-02-14
    • 2011-08-23
    • 2012-08-12
    相关资源
    最近更新 更多