事务(Windows 事件)

适用于:Windows |Windows服务器

事务

ESE 事务是处理逻辑单元,用于控制应用程序在数据库中查看和操作行的方式。 应用程序可以使用事务保存点来确定是保留还是放弃对数据库的一组特定更改。 ESE 中的所有事务都是原子、一致、隔离和持久 (ACID) ,如下所示:

  • 原子: 事务中的所有更新都显示在数据库中,或者被丢弃。
  • 一致: 数据库将始终以法律状态启动,并且始终以另一个法律状态结束。 对于 ESE 应用程序,数据库引擎将控制一些简单的约束,例如唯一索引的唯一性,但应用程序本身将定义数据库在法律状态所指的几乎所有其他方面。
  • 分离: 事务与其他会话的更新隔离。 事务永远不会看到另一个事务进行的一组部分更改。
  • 耐用: 数据库引擎确认事务已提交后,其更改将持久保存在数据库中。 出于性能原因,可以选择放弃事务的持久性。

事务在对 JetBeginTransactionJetCommitTransactionJetRollback 的调用范围内执行。 当应用程序进入事务时,数据库在事务开始时在实例上显示为冻结。 这称为快照隔离。 如果事务通过调用 JetRollback 终止,则事务中执行的任何操作都不会提交到数据库。 如果在调用 JetCommitTransaction 之前进程或计算机崩溃,则它与调用 JetRollback 相同。

此过程演示如何启动和提交读取和更新数据库中数据的事务。

启动和提交事务

  1. 使用会话 ID 调用 JetBeginTransactionJetBeginTransaction2 以启动事务。

  2. 通过在 cRow 参数中指定的JET_MoveFirst调用 JetMove,将光标移动到所需记录。 有关如何移动游标的详细信息,请参阅 表主题中的索引

  3. 在当前记录上调用 JetGetTableColumnInfo ,并在 InfoLevel 参数中指定的JET_ColInfo来检索列的列 ID。 列 ID 在 JET_COLUMNDEF 结构中返回。

  4. 使用更新的列的会话 ID、表 ID 和列 ID 调用 JetSetColumn 。 列数据包含在 pvData 参数中。

  5. 调用 JetCommitTransaction 将事务提交到数据库。

ESE 数据库引擎实现快照隔离的方式与传统关系数据库隔离和锁定模型有一些重要区别。 当事务读取行时,它始终可以访问该行,而不会失败或等待其他会话释放锁。 当事务尝试更新行时,如果它是第一个更新该行的会话,即第一个编写器获胜,它将成功。 如果会话不是第一个编写器,它将立即失败并出现写入冲突错误。 然后,会话必须中止其事务,通常通过随机延迟) 等待 (,以便其他事务提交其更改,然后重试事务。 数据库引擎不会自动导致该会话等待,直到其他事务完成其更新。 通常,事务将测试它是否可以更新 JetUpdate 调用内的行。 如果无法锁定更新的行, JetUpdate 将失败并JET_errWriteConflict。

从事务开始到事务结束时,会话限制为一个线程。 建议在事务中执行所有更新和检索操作。 ESE 还支持架构修改,例如在事务中创建表和添加列。 更新和架构修改都可以在同一事务中执行。 使用 JetCommitTransaction 完成事务后,更新将记录在事务日志文件中。 这些文件可用于在发生意外进程终止或系统关闭时保持逻辑一致状态。

事务最多可以嵌套 7 个级别,并相互嵌套对 JetBeginTransactionJetCommitTransactionJetRollback 的匹配调用。 这允许应用程序回滚事务的一部分,而无需备份整个事务。 对 JetCommitTransaction 的嵌套调用表示此处理级别已完成;但是,在使用 JetCommitTransaction 提交事务的最外部调用之前,事务不会提交到数据库。

托管更新列可以同时由多个会话更新,而无需Jet_errWriteConflict失败。 JetEscrowUpdate 函数只能在托管列(使用 Jet_bitColumnEscrowUpdate 创建的列)上调用。