public void TestWriteLock() { var systemClock = new SystemClock(); var site = new Site(1, new SiteList(systemClock), systemClock); var tempVariable = new Variable(1, site, systemClock); var transactionOne = new Transaction("T1", systemClock); var transactionTwo = new Transaction("T2", systemClock); var result = tempVariable.GetWriteLock(transactionOne); Assert.IsTrue(result.Contains(transactionOne)); Assert.IsTrue(tempVariable.WriteLockHolder == transactionOne); var resultTwo = tempVariable.GetReadLock(transactionTwo); Assert.IsFalse(resultTwo.Contains(transactionTwo)); Assert.IsTrue(resultTwo.Contains(transactionOne)); var resultThree = tempVariable.GetWriteLock(transactionTwo); Assert.IsFalse(resultThree.Contains(transactionTwo)); Assert.IsTrue(resultThree.Contains(transactionOne)); tempVariable.RemoveWriteLock(transactionOne); Assert.IsTrue(tempVariable.WriteLockHolder == null); }
public void AddTransaction(Transaction tempTransaction) { if (Transactions.Where(x => x.Id == tempTransaction.Id).Count() != 0) throw new Exception("Error: Detected Duplicate Transaction Id:" + tempTransaction.Id); Transactions.Add(tempTransaction); }
public BeginTransaction(string commandText, TransactionList transactionList, SiteList siteList, SystemClock systemClock) : base(commandText, transactionList, siteList, systemClock) { string[] info = commandText.Split(new[] {'(', ')'}); if (info.Length != 3) throw new Exception("Invalid command format: " + commandText); Transaction = new Transaction(info[1], systemClock) {IsReadOnly = info[0].ToLower().Equals("beginro")}; transactionList.AddTransaction(Transaction); }
/// <summary> /// Commits the transaction. /// </summary> /// <param name="transaction">The transaction.</param> public static void CommitTransaction(Transaction transaction) { foreach (Site tempSite in transaction.LocksHeld) { foreach (Variable tempVar in tempSite.VariableList) { tempVar.RemoveReadLock(transaction); //remove any read locks we might have if(tempVar.WriteLockHolder==transaction) { tempVar.CommitValue(); tempVar.RemoveWriteLock(transaction); } } } }
/// <summary> /// Aborts a given transaction. /// </summary> /// <param name="transaction">The transaction.</param> public static void AbortTransaction(Transaction transaction) { transaction.Status = TransactionStatus.Aborted; foreach (Site tempSite in transaction.LocksHeld) { var variableList = tempSite.VariableList; foreach (Variable tempVariable in variableList) { tempVariable.RemoveReadLock(transaction); if (tempVariable.WriteLockHolder == transaction) { tempVariable.RemoveWriteLock(transaction); tempVariable.ClearUncomitted(); } } } }
/// <summary> /// If the transaction should abort, if not, it waits. /// </summary> /// <param name="variableToAccess">The variable to access.</param> /// <param name="transactionSeekingLock">The transaction seeking lock.</param> public static bool ShouldAbort(Variable variableToAccess, Transaction transactionSeekingLock) { bool shouldAbort = false; //if we try to access a lock held by an older transaction if (variableToAccess.WriteLockHolder != null && variableToAccess.WriteLockHolder.StartTime < transactionSeekingLock.StartTime) return true; //we abort else { //if we are waiting on a younger transaction to finish if (variableToAccess.WriteLockHolder != null && variableToAccess.WriteLockHolder.StartTime > transactionSeekingLock.StartTime) shouldAbort = false; //check the read locks foreach (Transaction tempTrans in variableToAccess.ReadLockHolders) { if (tempTrans.StartTime < transactionSeekingLock.StartTime) shouldAbort = true; } } return shouldAbort; }
public void TestVariableResetOnFailure() { var systemClock = new SystemClock(); var site = new Site(1, new SiteList(systemClock), systemClock); var variable = new Variable(1, site, systemClock); var transactionOne = new Transaction("T1", systemClock); variable.GetReadLock(transactionOne); variable.GetWriteLock(transactionOne); Assert.IsTrue(variable.IsReadLocked); Assert.IsTrue(variable.IsWriteLocked); Assert.IsTrue(variable.ReadLockHolders.Contains(transactionOne)); Assert.IsTrue(variable.WriteLockHolder == transactionOne); variable.ResetToComitted(); Assert.IsFalse(variable.IsReadLocked); Assert.IsFalse(variable.IsWriteLocked); Assert.IsFalse(variable.ReadLockHolders.Contains(transactionOne)); Assert.IsFalse(variable.WriteLockHolder == transactionOne); }
public void TestAcquireAndRemoveReadLock() { var systemClock = new SystemClock(); var site = new Site(1, new SiteList(systemClock), systemClock); var tempVariable = new Variable(1, site, systemClock); var transactionOne = new Transaction("T1", systemClock); var transactionTwo = new Transaction("T2", systemClock); var result = tempVariable.GetReadLock(transactionOne); Assert.IsTrue(result.Contains(transactionOne)); var result2 = tempVariable.GetReadLock(transactionTwo); Assert.IsTrue(result.Contains(transactionOne)); Assert.IsTrue(result.Contains(transactionTwo)); tempVariable.RemoveReadLock(transactionOne); Assert.IsFalse(tempVariable.ReadLockHolders.Contains(transactionOne)); tempVariable.RemoveReadLock(transactionTwo); Assert.IsFalse(tempVariable.ReadLockHolders.Contains(transactionTwo)); }
//[TestMethod] public void TestMethod1() { var systemClock = new SystemClock(); var siteList = new SiteList(systemClock); var siteOne = new Site(1, siteList, systemClock); var siteTwo = new Site(2, siteList, systemClock); siteList.AddSite(siteOne); siteList.AddSite(siteTwo); var variableOne = new Variable(2, siteOne, systemClock); var variableTwo = new Variable(2, siteTwo, systemClock); var transaction = new Transaction("test", systemClock); siteOne.VariableList.Add(variableOne); siteTwo.VariableList.Add(variableTwo); Assert.IsTrue(variableOne.GetWriteLock(transaction).Contains(transaction)); Assert.IsTrue(variableTwo.GetWriteLock(transaction).Contains(transaction)); variableOne.Set("5"); variableOne.CommitValue(); variableOne.Set("4"); var affectedTranasactions = siteOne.Fail(); Assert.IsTrue(siteOne.IsFailed); siteOne.Recover(); Assert.IsTrue(affectedTranasactions.Contains(transaction)); Assert.IsTrue( transaction.AwaitingReReplication.Contains(new ValueSitePair() { Site = siteOne, Variable = variableOne })); Assert.IsFalse(siteOne.IsFailed); }
public static void BlockTransaction(Transaction transaction, BaseAction blockedAction) { transaction.Status = TransactionStatus.Blocked; transaction.QueuedCommands.Enqueue(blockedAction); }
/// <summary> /// Removes the write lock if the given transaction holds it /// </summary> /// <param name="tempTransaction">The temp transaction.</param> public void RemoveWriteLock(Transaction tempTransaction) { if (WriteLockHolder == tempTransaction) WriteLockHolder = null; }
/// <summary> /// Attempts go get a write lock. Returns a list of transaction holding the lock, if it doesnt /// include the given transaction, the lock failed. This also checks to see if there is a read /// lock and will return those transaction too. /// </summary> /// <param name="tempTransaction">The temp transaction.</param> /// <returns>List of transaction holding the lock.</returns> public List<Transaction> GetWriteLock(Transaction tempTransaction) { //we cant get a write lock if there are write lock holders //so lets check that first if (IsReadLocked) { //maybe the same transaction holds the only read lock //in which case we can give it the write lock if (ReadLockHolders.Count == 1 && ReadLockHolders.Contains(tempTransaction)) { WriteLockHolder = tempTransaction; tempTransaction.AddLockHeldLocation(Site); return new List<Transaction> {WriteLockHolder}; } else //it doesnt, sad panda { return ReadLockHolders; } } if (IsWriteLocked) { return new List<Transaction> {WriteLockHolder}; } else { WriteLockHolder = tempTransaction; tempTransaction.AddLockHeldLocation(Site); return new List<Transaction> {WriteLockHolder}; } }
/// <summary> /// Gets the value. /// </summary> /// <param name="tempTransaction">The temp transaction.</param> /// <returns></returns> public string GetValue(Transaction tempTransaction = null) { if (WriteLockHolder != null && tempTransaction == WriteLockHolder && UncomittedValue != String.Empty) return UncomittedValue; if (VariableHistory.Count != 0) { if (tempTransaction != null && tempTransaction.IsReadOnly) { return VariableHistory.Where(x => x.TimeStamp <= tempTransaction.StartTime).OrderByDescending( (x => x.TimeStamp)).First().Value; } return VariableHistory.OrderByDescending((x => x.TimeStamp)).First().Value; } return null; }
/// <summary> /// Attempts to get a read lock. Returns a list of transactions holding the lock, /// if it doesnt include the given transaction, the lock failed. This also /// check to see if there is a write lock and will return that transaction too. /// </summary> /// <param name="tempTransaction">The temp transaction.</param> /// <returns>List of transactions holding the lock.</returns> public List<Transaction> GetReadLock(Transaction tempTransaction) { //check to see if the there is currently a write lock if (IsWriteLocked && !WriteLockHolder.Equals(tempTransaction)) //they don't hold the write lock return new List<Transaction> {WriteLockHolder}; else if (IsWriteLocked && WriteLockHolder.Equals(tempTransaction)) { //they do hold the write lock return new List<Transaction> {WriteLockHolder}; } //there is no write lock, so add the transaction to the list of read lock holders if (!ReadLockHolders.Contains(tempTransaction)) { ReadLockHolders.Add(tempTransaction); tempTransaction.AddLockHeldLocation(Site); } return ReadLockHolders; }
/// <summary> /// Rereplicates any data that had to wait for a transaction to end. /// </summary> /// <param name="transaction">The transaction.</param> private static void ProcessReReplication(Transaction transaction) { //only if there are things to actually rereplicate if (transaction.AwaitingReReplication.Count == 0) return; string output = "Rereplicating: "; foreach (ValueSitePair pair in transaction.AwaitingReReplication) { List<Site> available = _siteList.GetRunningSitesWithVariable(pair.Variable.Id.ToString()); Variable goodVariable = available.First().GetVariable(pair.Variable.Id.ToString()); pair.Variable.VariableHistory = goodVariable.VariableHistory; pair.Variable.IsReadable = true; output = output + pair; } State.Add(output); }
/// <summary> /// Removes the read lock if the given transaction holds it. /// </summary> /// <param name="tempTransaction">The temp transaction.</param> public void RemoveReadLock(Transaction tempTransaction) { if (ReadLockHolders.Contains(tempTransaction)) ReadLockHolders.Remove(tempTransaction); }
/// <summary> /// Determines whether the specified transaction has locks on a variable at this site. /// </summary> /// <param name="transaction">The transaction.</param> /// <returns> /// <c>true</c> if the specified transaction has locks; otherwise, <c>false</c>. /// </returns> public bool HasLocks(Transaction transaction) { return true; }