public async Task <Releaser> AcquireLock(ulong pageId, LockTypeEnum lockType) { int lockId = lockManager.LockIdForPage(pageId); if (lockType != LockTypeEnum.Shared) { throw new ReadOnlyTranCantAcquireExLockException(); } lock (lck) { if (locksHeld.ContainsKey(lockId)) { // Return dummy leaser. You don't really own this lock. // This probably needs to change. throw new TranAlreadyHoldingLock(); } } var releaser = await lockManager.AcquireLock(lockType, pageId, this.transactionId); lock (lck) { locksHeld.Add(lockId, lockType); } releaser.SetReleaseCallback(() => this.ReleaseLock(lockId)); return(releaser); }
private async Task <Releaser> AcquireLockInternal(ulong pageId, LockTypeEnum lockType, bool forceCallerOwnership) { ILockManager lockManager = this.pageManager.GetLockManager(); int lockId = lockManager.LockIdForPage(pageId); lock (lck) { if (locksHeld.ContainsKey(lockId)) { return(new Releaser()); } } var releaser = await lockManager.AcquireLock(lockType, pageId, this.transactionId).ConfigureAwait(continueOnCapturedContext: false); lock (lck) { locksHeld.Add(lockId, lockType); } releaser.SetReleaseCallback(() => this.ReleaseLockCallback(lockId)); if (forceCallerOwnership) { return(releaser); } // TODO: Implement Isolation Level strategy. if (this.isolationLevel == IsolationLevelEnum.ReadCommitted) { // If this is a read lock return to caller. // If write transaction is the owner. if (lockType == LockTypeEnum.Shared) { return(releaser); } else if (lockType == LockTypeEnum.Exclusive) { this.myLocks.Add(releaser); return(new Releaser()); } else { throw new InvalidProgramException(); } } else { throw new InvalidProgramException(); } }
public bool AmIHoldingALock(ulong pageId, out LockTypeEnum lockType) { ILockManager lockManager = this.pageManager.GetLockManager(); int lockId = lockManager.LockIdForPage(pageId); lock (lck) { if (locksHeld.TryGetValue(lockId, out LockTypeEnum myLock)) { lockType = myLock; return(true); } } lockType = LockTypeEnum.Shared; return(false); }