@itwin/core-backend
Version:
iTwin.js backend components
157 lines • 9.01 kB
TypeScript
/** @packageDocumentation
* @module iModels
*/
import { Id64Arg, Id64String } from "@itwin/core-bentley";
import { _close, _elementWasCreated, _implementationProhibited, _releaseAllLocks } from "./internal/Symbols";
/**
* Interface for acquiring element locks to [coordinate simultaneous edits]($docs/learning/backend/ConcurrencyControl.md) from multiple briefcases.
* @see [[IModelDb.locks]] to access the locks for an iModel.
* @public
*/
export interface LockControl {
/** @internal*/
readonly [_implementationProhibited]: unknown;
/**
* true if this LockControl uses a server-based concurrency approach.
*/
readonly isServerBased: boolean;
/**
* Close the local lock control database
* @internal
*/
[_close]: () => void;
/**
* Notification that a new element was just created. Called by [[Element.onInserted]]
* @internal
*/
[_elementWasCreated]: (id: Id64String) => void;
/**
* Throw if locks are required and the exclusive lock is not held on the supplied element.
* Note: there is no need to check the shared locks on parents/models since an element cannot hold the exclusive lock without first obtaining them.
* Called by functions like [[Element.onUpdate]], [[Element.onDelete]], etc.
*/
checkExclusiveLock(id: Id64String, type: string, operation: string): void;
/**
* Throw if locks are required and a shared lock is not held on the supplied element.
* Called by [[Element.onInsert]] to ensure shared lock is held on the new element's model and parent element.
*/
checkSharedLock(id: Id64String, type: string, operation: string): void;
/**
* Determine whether the owning iModel currently holds the exclusive lock on the specified element.
*/
holdsExclusiveLock(id: Id64String): boolean;
/**
* Determine whether the owning iModel currently holds a shared lock on the specified element.
*/
holdsSharedLock(id: Id64String): boolean;
/**
* Acquire locks on one or more elements from the lock server, if required and not already held.
* If any required lock is not available, this method throws an exception and *none* of the requested locks are acquired.
* @note Acquiring the exclusive lock on an element requires also obtaining a shared lock on all its owner elements. This method will
* attempt to acquire all necessary locks for both sets of input ids.
* @note Calling this method after reversing or reinstating a Txn indicates the start of a brand new Txn with the current Txn ID,
* making it invalid to call [[abandonLocksForReversedTxn]] or [[acquireLocksForReinstatingTxn]] for previously-reversed
* Txns with the current ID or greater.
*/
acquireLocks(arg: {
/** if present, one or more elements to obtain shared lock */
shared?: Id64Arg;
/** if present, one or more elements to obtain exclusive lock */
exclusive?: Id64Arg;
}): Promise<void>;
/** Release all locks currently held by this briefcase from the lock server after editing the associated elements.
* This is typically done on your behalf by [[BriefcaseDb.pushChanges]].
* If you are abandoning changes instead of pushing them, you should call [[abandonAllLocks]] instead.
* You may want to do it manually when abandoning all of your briefcase's local changes.
* You cannot release your locks if your briefcase contains local changes.
* @throws Error if the briefcase has local changes, or if any other error occurs while releasing the locks.
*/
releaseAllLocks(): Promise<void>;
/**
* Abandons all locks currently held by this briefcase when none of the associated elements have
* been or will be modified. This is only valid to do when none of the elements protected by
* the currently-held locks have been edited, or if all edits have been reversed or abandoned without
* pushing them.
* @beta
*
* The locks are released on the IModelHub, but the changeset associated with the locks is not updated,
* reflecting the fact that the associated elements were not edited.
*/
abandonAllLocks(): Promise<void>;
/**
* Release all locks currently held by this Briefcase from the lock server.
* Not possible to release locks unless push or abandon all changes. Should only be called internally.
* @internal
*/
[_releaseAllLocks]: () => Promise<void>;
/**
* Abandons the locks that were acquired during a given Txn and all later Txns, all of which must already
* have been reversed.
* @beta
*
* @param txnId The ID of the first Txn whose locks should be abandoned. This must either be a Txn that has
* already been reversed, or the [[TxnManager.getCurrentTxnId]]. In either case, the current Txn must not
* have any unsaved changes.
* @returns A promise that resolves to true if any locks were successfully abandoned. False if there were no locks to abandon,
* which may be the case if the Txns did not acquire any locks or if they were already abandoned. The Promise rejects
* with an ITwinError if the Txn has not been reversed, the current Txn has unsaved changes, or if any other error occurs
* while releasing the locks.
* @note This method also implicitly calls [[abandonLocksForCurrentUnsavedTxn]]. Locks acquired in the current,
* unsaved Txn will be abandoned when calling this method. However, they can not be re-acquired using
* [[acquireLocksForReinstatingTxn]]. This is because there is no way to recover these unsaved changes after abandoning
* them, so it is rarely useful to re-acquire the locks associated with irrecoverable changes.
*/
abandonLocksForReversedTxn(txnId: Id64String): Promise<boolean>;
/**
* Abandons the locks that were acquired during the current, unsaved Txn. Any changes in the unsaved Txn must be abandoned
* before calling this method.
* @beta
*
* @returns A promise that resolves to true if any locks were successfully abandoned. False if there were no locks to abandon,
* which may be the case if the current Txn did not acquire any locks or if they were already abandoned. The Promise rejects
* with an ITwinError if the current Txn has unsaved changes, or if any other error occurs while releasing the locks.
*/
abandonLocksForCurrentUnsavedTxn(): Promise<boolean>;
/**
* Re-acquire the locks that were previously acquired during a given Txn and all previous Txns. These locks are
* expected to have previously been released with {@link LockControl.abandonLocksForReversedTxn}. This is used
* just before reinstating a previously-reversed Txn to ensure that the necessary locks are held for the
* reinstated changes.
* @beta
*
* It is possible that the locks may no longer be available, in which case the returned Promise will reject
* with an exception.
*
* @param txnId The ID of the last Txn whose locks should be re-acquired.
* @returns A promise that resolves to true if any locks were successfully acquired. False if there were no locks to acquire,
* which may be the case if the Txn in question did not acquire any locks or if they were already re-acquired. The Promise
* rejects with an ITwinError if the Txn does not exist, the current Txn has unsaved changes, the locks cannot be acquired,
* or if any other error occurs while acquiring the locks.
*/
acquireLocksForReinstatingTxn(txnId: Id64String): Promise<boolean>;
/**
* Checks whether the locks originally acquired for a specified reversed Txn, and all earlier Txns, were either not abandoned
* or have already been re-acquired.
* @beta
*
* If this method returns true, it is safe to reinstate the given Txn with [[TxnManager.reinstateTxn]]. If it returns false,
* the necessary locks must be acquired first, either by calling [[TxnManager.reinstateTxnAsync]] or by explicitly calling
* [[acquireLocksForReinstatingTxn]] first.
*
* @param txnId The ID of the Txn to check.
* @returns True if the necessary locks are currently held, false otherwise.
*/
holdsNecessaryLocksForReinstatingTxn(txnId: Id64String): boolean;
/**
* Clears the records of locks acquired for a given Txn and all later Txns from the local lock database. Call this after
* a Txn becomes unreachable. This allows an ID to potentially be reused for a different Txn in the future.
* @beta
*
* After invoking this method, {@link LockControl.abandonLocksForReversedTxn} and {@link LockControl.acquireLocksForReinstatingTxn} will no
* longer be able to operate on this Txn or any later Txns.
*
* @param txnId The ID of the first Txn whose lock records should be cleared.
*/
clearTxnLockRecords(txnId: Id64String): void;
}
//# sourceMappingURL=LockControl.d.ts.map