JetEscrowUpdate 函数

适用于: Windows |Windows Server

JetEscrowUpdate 函数

JetEscrowUpdate 函数对一列执行原子加法运算。 此函数允许多个会话同时更新同一记录,而不会发生冲突。

    JET_ERR JET_API JetEscrowUpdate(
      __in          JET_SESID sesid,
      __in          JET_TABLEID tableid,
      __in          JET_COLUMNID columnid,
      __in          void* pv,
      __in          unsigned long cbMax,
      __out_opt     void* pvOld,
      __in          unsigned long cbOldMax,
      __out_opt     unsigned long* pcbOldActual,
      __in          JET_GRBIT grbit
    );

parameters

sesid

用于此调用的会话。

tableid

用于此调用的游标。

columnid

要更新的列的 columnid

pv

指向包含列的附录的缓冲区的指针。

cbMax

包含该附录的缓冲区的大小。

pvOld

) 忽略将接收存储在数据库中的列的当前值的输出缓冲区 (版本控制。

cbOldMax

将接收列的当前值的输出缓冲区的最大大小。 目前仅支持JET_coltypLong,因此缓冲区的长度必须为 4 个字节或 0 个字节。 如果 pvOld 为 NULL,则 cbOldMax 应为 0。

线路板OldActual

接收在输出缓冲区中接收的实际原始值数据量。

grbit

一组指定以下选项的零个或多个位。

含义

JET_bitEscrowNoRollback

即使执行托管更新的会话具有其事务回滚,也不会撤消此更新。 请注意,由于日志记录可能不会刷新到磁盘,因此如果发生崩溃,则使用此标志完成的最近托管更新可能会丢失。

返回值

此函数返回具有以下返回代码之一 的JET_ERR 数据类型。 有关可能的 ESE 错误的详细信息,请参阅 可扩展存储引擎错误错误处理参数

返回代码

说明

JET_errSuccess

操作已成功完成。

JET_errAlreadyPrepared

游标具有使用 JetPrepareUpdate 准备的更新。

JET_errClientRequestToStopJetService

无法完成操作,因为由于调用 JetStopService,与会话关联的实例上的所有活动都已停止。

JET_errInstanceUnavailable

无法完成该操作,因为与会话关联的实例遇到一个致命错误,该错误要求撤销对所有数据的访问以保护该数据的完整性。 此错误仅由 Windows XP 和更高版本返回。

JET_errInvalidBufferSize

传入的缓冲区大小无效。 目前仅支持JET_coltypLong,因此缓冲区必须为 4 个字节。

JET_errInvalidOperation

指定的列无效。 必须使用指定JET_bitColumnEscrowUpdate来创建列。 只能将JET_coltypLong的固定列指定为可托管更新列。

JET_errNoCurrentRecord

游标必须位于记录上才能更新列。

JET_errNotInTransaction

托管更新只能由事务中的会话执行。

JET_errNotInitialized

无法完成操作,因为尚未初始化与会话关联的实例。

JET_errPermissionDenied

游标不能是只读的,不能更新记录。

JET_errRestoreInProgress

无法完成操作,因为正在与会话关联的实例上执行还原操作。

JET_errSessionSharingViolation

不能同时从多个线程使用同一会话。 此错误仅由 Windows XP 和更高版本返回。

JET_errTermInProgress

无法完成操作,因为与会话关联的实例正在关闭。

JET_errTransReadOnly

会话必须具有写入权限才能更新记录。

JET_errWriteConflict

请求冲突的更新时返回的错误。

备注

通常,如果两个会话尝试同时更新记录,除非会话完全序列化,否则第二个会话将收到JET_errWriteConflict错误。 若要序列化更新同一记录的两个会话,第二个会话必须在第一个事务提交其事务后启动其事务。 有关详细信息 ,请参阅 JetBeginTransaction

可以托管更新同一记录中的多个列。 更新不会相互影响。

只有 JetEscrowUpdate 操作彼此兼容。 如果两个不同的会话尝试准备更新或删除同一条记录,将生成写入冲突。

会话 B
JetEscrowUpdate

JetPrepareUpdate

JetDelete

JetEscrowUpdate

JET_errSuccess

JET_errWriteConflict

JET_errWriteConflict

JetUpdate

JET_errWriteConflict

JET_errWriteConflict

JET_errWriteConflict

会话 A

JetDelete

JET_errWriteConflict

JET_errWriteConflict

JET_errWriteConflict

除非) 指定了JET_bitEscrowNoRollback,否则托管操作是使用 JetRollback (进行版本控制并撤消的。 JetEscrowUpdate 返回存储在数据库中的列的原始值,因为应用程序可能需要在命中 sentinel 值时执行特殊操作。 JetRetrieveColumn 返回列的正确版本控制视图,忽略并发会话进行的更新。

给定在相同记录的同一列上运行的两个会话,我们可以看到其工作原理。 假设列以值 0 开头。

会话

Operation

存储值

返回值

A

JetBeginTransation

A

JetBeginTransation

0

A

JetEscrowUpdate (4)

4

0

A

JetRetrieveColumn

4

B

JetBeginTransaction

B

JetRetrieveColumn

0

B

JetEscrowUpdate (3)

7

4

B

JetRetrieveColumn

3

A

JetEscrowUpdate (2)

9

7

A

JetEscrowUpdate (-7)

2

9

B

JetRetrieveColumn

3

A

JetRetrieveColumn

-1

B

JetRollback

-1

A

JetRetrieveColumn

-1

不建议替换执行记录托管更新的同一事务中的记录。 具体而言,如果记录的更新是用一个 JET_TABLEID 准备的,并且使用不同的 JET_TABLEID 来托管更新记录,则在调用 JetUpdate 时,更新的托管将丢失。 即使更新期间未设置托管列,也会发生这种情况。

当托管可更新列的值为零时,可以触发特殊行为。 仅当 JetEscrowUpdate 操作导致列值为零时,才会发生此行为。 该操作不会立即发生,而是发生在事务之后的某个时候,导致列的提交值为零。 如果其他会话没有修改列) ,则列的值仍为零 (。 如果列是使用 JET_bitColumnDeleteOnZero 创建的,则将删除包含该列的记录。 如果列是使用 JET_bitColumnFinalize则发出回调。 崩溃可能会导致这些操作不发生,但使用 JetDefragment 函数的联机维护 () 将正确地重做这些操作。

要求

要求

客户端

需要 Windows Vista、Windows XP 或 Windows 2000 Professional。

服务器

需要 Windows Server 2008、Windows Server 2003 或 Windows 2000 Server。

标头

在 Esent.h 中声明。

Library

使用 ESENT.lib。

DLL

需要ESENT.dll。

另请参阅

JET_COLUMNID
JET_ERR
JET_GRBIT
JET_SESID
JET_TABLEID
JetBeginTransaction
JetDefragment
JetPrepareUpdate
JetRetrieveColumn
JetRollback
JetStopService
JetUpdate