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 |
JET_errSuccess |
JET_errWriteConflict |
JET_errWriteConflict |
|
JET_errWriteConflict |
JET_errWriteConflict |
JET_errWriteConflict |
||
会话 A |
JET_errWriteConflict |
JET_errWriteConflict |
JET_errWriteConflict |
除非) 指定了JET_bitEscrowNoRollback,否则托管操作是使用 JetRollback (进行版本控制并撤消的。 JetEscrowUpdate 返回存储在数据库中的列的原始值,因为应用程序可能需要在命中 sentinel 值时执行特殊操作。 JetRetrieveColumn 返回列的正确版本控制视图,忽略并发会话进行的更新。
给定在相同记录的同一列上运行的两个会话,我们可以看到其工作原理。 假设列以值 0 开头。
会话 |
Operation |
存储值 |
返回值 |
---|---|---|---|
A |
|||
A |
0 |
||
A |
JetEscrowUpdate (4) |
4 |
0 |
A |
4 |
||
B |
|||
B |
0 |
||
B |
JetEscrowUpdate (3) |
7 |
4 |
B |
3 |
||
A |
JetEscrowUpdate (2) |
9 |
7 |
A |
JetEscrowUpdate (-7) |
2 |
9 |
B |
3 |
||
A |
-1 |
||
B |
-1 |
||
A |
-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