JetEscrowUpdate 函数

适用于:Windows |Windows服务器

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
    );

参数

sesid

用于此调用的会话。

tableid

要用于此调用的游标。

columnid

要更新的列的 columnid

pv

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

cbMax

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

pvOld

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

cbOldMax

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

idOldActual

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

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

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

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

会话

操作

存储的值

返回值

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。

Server

需要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