/// <summary> /// create new rec lock then waitting /// </summary> /// <param name="ctx"></param> /// <param name="entry"></param> /// <returns></returns> private DBResult CreateRecLockForWait(ref LockContext ctx, out LockEntry entry) { var recEntry = CreateRecLock(ref ctx); if (!recEntry.IsWaiting) { recEntry.Flags |= LockFlags.Waiting; } entry = recEntry; entry.Transaction.WaitLock = recEntry; entry.Transaction.State = TransactionState.Waitting; //check dead-lock if (IsCausedDeadLock(recEntry)) { entry.Flags &= ~LockFlags.Waiting; entry.SetBit(ctx.RecordIndex, 0); entry.Transaction.WaitLock = null; return(DBResult.DeadLock); } entry.Transaction.WaitEvent.Reset(); return(DBResult.WaitLock); }
/// <summary> /// create a new rec-lock /// </summary> /// <param name="ctx"></param> /// <returns></returns> private LockEntry CreateRecLock(ref LockContext ctx) { if (!RecLocks.TryGetValue(ctx.Page, out var list)) { list = new LinkedList <LockEntry>(); RecLocks[ctx.Page] = list;; } var tx = ctx.Transaction; var entry = new LockEntry(ctx.Page, ctx.Flags, ctx.RecordCount); if (entry.IsWaiting) { tx.WaitLock = entry; } list.AddLast(entry); tx.Locks.AddLast(entry); entry.GNode = list.Last; entry.TNode = tx.Locks.Last; entry.Index = ctx.Index; entry.Transaction = ctx.Transaction; entry.Thread = Thread.CurrentThread.ManagedThreadId; entry.SetBit(ctx.RecordIndex, 1); return(entry); }