internal SimpleTransactionLogger(XDocument m, SimpleTransaction t) { model = m; tx = t; undoCommands = new List<XmlModelCommand>(); txCommands = new List<XmlModelCommand>(); nodesAdded = new Dictionary<XObject, object>(); var provider = tx.Provider as VanillaXmlModelProvider; if ((provider == null || provider.CommandFactory == null)) { cmdFactory = new CommandFactory(); } else { cmdFactory = provider.CommandFactory; } }
internal SimpleTransaction( VanillaXmlModelProvider provider, string name, SimpleTransaction parent, SimpleTransactionManager mgr, object userState) { this.provider = provider; this.name = name; this.parent = parent; manager = mgr; DesignerTransaction = true; resources = new Dictionary<XDocument, SimpleTransactionLogger>(); status = XmlTransactionStatus.Active; _userState = userState; }
internal void AppendCommands(SimpleTransaction childTransaction) { foreach (var doc in childTransaction.resources.Keys) { var logger = resources[doc]; foreach (var cmd in childTransaction.resources[doc].TxCommands) { logger.AddCommand(cmd); } foreach (var cmd in childTransaction.resources[doc].UndoCommands) { logger.AddCommand(cmd); } } }
internal void FireTransactionCompleted(SimpleTransaction tx) { OnTransactionCompleted(new XmlTransactionEventArgs(tx, tx.DesignerTransaction)); }
public virtual bool CanRedo(SimpleTransaction tx) { return true; }
public void LockForWrite(SimpleTransaction txId, object doc) { Lock(txId, doc, LockMode.Write); }
public void UnlockAll(SimpleTransaction txId) { ResourceEntry lockTarget = null; lock (_resourceTable) { IDictionaryEnumerator resenum = _resourceTable.GetEnumerator(); while (resenum.MoveNext()) { lockTarget = resenum.Value as ResourceEntry; if (lockTarget == null) { continue; } lock (lockTarget) { for (var lockMode = (int)LockMode.Read; lockMode < (int)LockMode._Length; lockMode++) { lockTarget.Unregister(txId, (LockMode)lockMode); } } } } }
public void Lock(SimpleTransaction txId, object resource, LockMode mode) { ResourceEntry lockTarget = null; lock (_resourceTable) { lockTarget = GetResoureEntry(resource); if (lockTarget == null) { lockTarget = new ResourceEntry(); _resourceTable[resource] = lockTarget; } } for (var c = 0;; c++) { if (c > 0) { if (!lockTarget.UnlockEvent.WaitOne(5000, false)) { throw new XmlTransactionException("DeadLock Detected..."); } } lock (lockTarget) { var oldLockMode = lockTarget.GetExistingLockMode(txId); if (oldLockMode != LockMode.Null) { lockTarget.Unregister(txId, oldLockMode); } if (lockTarget.Compatible(mode)) { lockTarget.Register(txId, mode); return; } if (oldLockMode != LockMode.Null) { lockTarget.Register(txId, oldLockMode); } } } }
public void LockForRead(SimpleTransaction txId, object doc) { Lock(txId, doc, LockMode.Read); }
/// <summary> /// Release a lock on the passed in transaction context with /// the specified mode. Return immediately if the context does /// not hold a lock for this mode. /// </summary> /// <param name="context">the context for which to remove the lock</param> /// <param name="request">the mode of the lock to be released</param> public void Unregister(SimpleTransaction context, LockMode request) { // First get the hash table for this lock mode var transactionList = GetTransactionList(request); if (transactionList == null || !transactionList.ContainsKey(context)) { // This transaction wasn't registered, return immediately return; } transactionList.Remove(context); for (var l = request; l > LockMode.Null; _lockMode = --l) { // recalculate the strongest lock mode var nextTransactionList = GetTransactionList(l); if (nextTransactionList == null) { continue; } if (nextTransactionList.Count > 0) { break; } } if (request > _lockMode) { // if anyone was waiting for this lock, they should recheck if (_autoResetEvent != null) { _autoResetEvent.Set(); } } }
public LockMode GetExistingLockMode(SimpleTransaction txId) { for (var i = 0; i < (int)LockMode._Length; i++) { var tList = GetTransactionList((LockMode)i); if (tList != null && tList.ContainsKey(txId)) { return (LockMode)i; } } return LockMode.Null; }
public void Register(SimpleTransaction context, LockMode request) { var transactionList = GetTransactionList(request); if (transactionList == null) { transactionList = new Dictionary<SimpleTransaction, SimpleTransaction>(); _transactions[request] = transactionList; } // Add the transaction to the list for _request_ lock mode transactionList[context] = context; // Update the strongest lock mode, if necessary if (request > _lockMode) { _lockMode = request; } if (_autoResetEvent != null) { _autoResetEvent.Reset(); } }
internal void SetCurrentTransaction(VanillaXmlModelProvider provider, SimpleTransaction tx) { if (_currentTransaction.ContainsKey(provider)) { _currentTransaction[provider] = tx; } else { _currentTransaction.Add(provider, tx); } }
internal void Rollback(SimpleTransaction tx) { tx.MakeInactive(); var parent = tx.parent; // Unlock all resources held by this transaction if (parent != null) { parent.MakeActive(); } _currentTransaction[tx.provider] = parent; // Unlock Store only when Top-most Tx Completes if (parent == null) { SimpleLockManager.UnlockAll(tx); } // In case of Rollback we fire off event even for nested Tx tx.FireCompleted(); }
internal void Commit(SimpleTransaction tx) { tx.MakeInactive(); var parent = tx.parent; // Unlock all resources held by this transaction if (parent != null) { parent.MakeActive(); } _currentTransaction[tx.provider] = parent; // Fire Events and unlock Store only when Top-most Tx commits if (parent == null) { SimpleLockManager.UnlockAll(tx); tx.FireCompleted(); } }
internal SimpleTransaction BeginTransaction( VanillaXmlModelProvider provider, string name, SimpleTransaction parent, object userState) { var tx = new SimpleTransaction(provider, name, parent, this, userState); if (parent != null) { // Unsubscribe events on parent transaction parent.MakeInactive(); // Create SimpleTransactionLogger for each document in VanillaXmlModelProvider foreach (var model in provider.OpenXmlModels) { tx.EnlistResource(model as SimpleXmlModel); } } else { // This is the top level transaction, so acquire all locks to avoid deadlocks lock (this) { foreach (var model in provider.OpenXmlModels) { tx.LockForWrite(model as SimpleXmlModel); } } } // Make this the current Active transaction SetCurrentTransaction(provider, tx); tx.MakeActive(); return tx; }