/// <summary> /// Either give the writer a chance to finish it, abort it, or both. /// </summary> /// <param name="me">caller's XState object</param> /// <param name="writer">prior writer's XState object</param> public void ResolveConflict(XState me, XState writer) { if (writer.priority > me.priority) { writer.BlockWhileActiveAndNotWaiting(); // wait for same or higher priority } else { writer.Abort(); // abort lower priority } }
/// <summary> /// If prior transaction is /// active and higher priority, then wait. /// active and lower priority, then abort it. /// waiting and higher priority, then adopt its priority and abort it. /// waiting and lower priority, then abort it. /// </summary> /// <param name="me">caller's XState object</param> /// <param name="writer">prior writer's XState object</param> public void ResolveConflict(XState me, XState writer) { if (writer.waiting || writer.priority < me.priority) { writer.Abort(); } else { me.Waiting(); // announce that I'm waiting writer.BlockWhileActiveAndNotWaiting(); // wait for prior transaction to become not ACTIVE me.NotWaiting(); // announce that I'm no longer waiting } }
/// <summary> /// If exponential backoff fails, then abort the writer. /// </summary> /// <param name="me">caller's XState object</param> /// <param name="writer">prior writer's XState object</param> public void ResolveConflict(XState me, XState writer) { int sleep = random.Next(1 << attempts); Thread.Sleep(sleep); if (writer.State != XStates.ACTIVE) { attempts = 0; } else { writer.Abort(); // no more Mister Nice Guy. if (attempts < MAX_LOG_BACKOFF) { attempts++; } } return; }
/// <summary> /// Immediately abort the writer. /// </summary> /// <param name="me">caller's XState object</param> /// <param name="writer">prior writer's XState object</param> public void ResolveConflict(XState me, XState writer) { writer.Abort(); }