// ====================================================================== Transaction callback internal static void RemoveFromCache(NodeDataParticipant participant) // orig name: OnNodeDataCommit { // Do not fire any events if the node is new: // it cannot effect any other content if (participant.IsNewNode) { return; } var data = participant.Data; // Remove items from Cache by the OriginalPath, before getting an update // of a - occassionally differring - path from the database if (data.PathChanged) { PathDependency.FireChanged(data.OriginalPath); } if (data.ContentListTypeId != 0 && data.ContentListId == 0) { // If list, invalidate full subtree PathDependency.FireChanged(data.Path); } else { // If not a list, invalidate item NodeIdDependency.FireChanged(data.Id); } }
private static bool SaveNodeDataTransactional(Node node, NodeSaveSettings settings, out IndexDocumentData indexDocument) { indexDocument = null; var data = node.Data; var isNewNode = data.Id == 0; var isLocalTransaction = !TransactionScope.IsActive; if (isLocalTransaction) TransactionScope.Begin(); try { data.CreateSnapshotData(); var participant = new NodeDataParticipant { Data = data, Settings = settings, IsNewNode = isNewNode }; TransactionScope.Participate(participant); int lastMajorVersionId, lastMinorVersionId; DataProvider.Current.SaveNodeData(data, settings, out lastMajorVersionId, out lastMinorVersionId); //-- here we re-create the node head to insert it into the cache and refresh the version info if (lastMajorVersionId > 0 || lastMinorVersionId > 0) { var head = NodeHead.CreateFromNode(node, lastMinorVersionId, lastMajorVersionId); if (MustCache(node.NodeType)) { //-- participate cache items var idKey = CreateNodeHeadIdCacheKey(head.Id); var participant2 = new InsertCacheParticipant { CacheKey = idKey }; TransactionScope.Participate(participant2); var pathKey = CreateNodeHeadPathCacheKey(head.Path); var participant3 = new InsertCacheParticipant { CacheKey = pathKey }; TransactionScope.Participate(participant3); CacheNodeHead(head, idKey, pathKey); } node.RefreshVersionInfo(head); if (!settings.DeletableVersionIds.Contains(node.VersionId)) indexDocument = SaveIndexDocument(node); } if (isLocalTransaction) TransactionScope.Commit(); } catch (System.Data.Common.DbException dbe) { if (isLocalTransaction && IsDeadlockException(dbe)) return false; throw SavingExceptionHelper(data, dbe); } catch (Exception e) { var ee = SavingExceptionHelper(data, e); if (ee == e) throw; else throw ee; } finally { if (isLocalTransaction && TransactionScope.IsActive) TransactionScope.Rollback(); } return true; }
internal static void OnNodeDataRollback(NodeDataParticipant participant) { participant.Data.Rollback(); }
//====================================================================== Transaction callback internal static void OnNodeDataCommit(NodeDataParticipant participant) { //Do not fire any events if the node is new: //it cannot effect any other content if (participant.IsNewNode) return; var data = participant.Data; //var setting = participant.Settings; //foreach (var path in setting.InvalidatingPaths) // PathDependency.FireChanged(path); //foreach (var nodeId in setting.InvalidatingNodeIds) // NodeIdDependency.FireChanged(nodeId); ////foreach (var nodeId in setting.InvalidatingVersionIds) //// ??(); // Remove items from Cache by the OriginalPath, before getting an update // of a - occassionally differring - path from the database if (data.PathChanged) { PathDependency.FireChanged(data.OriginalPath); } if (data.ContentListTypeId != 0 && data.ContentListId == 0) { // If list, invalidate full subtree PathDependency.FireChanged(data.Path); } else { // If not a list, invalidate item NodeIdDependency.FireChanged(data.Id); } }
private static Exception SaveNodeDataTransactional(Node node, NodeSaveSettings settings, IIndexPopulator populator, string originalPath, string newPath) { IndexDocumentData indexDocument = null; bool hasBinary = false; var data = node.Data; var isNewNode = data.Id == 0; NodeDataParticipant participant = null; var msg = "Saving Node#" + node.Id + ", " + node.ParentPath + "/" + node.Name; var isLocalTransaction = !TransactionScope.IsActive; using (var op = SnTrace.Database.StartOperation(msg)) { if (isLocalTransaction) { TransactionScope.Begin(); } try { // collect data for populator var populatorData = populator.BeginPopulateNode(node, settings, originalPath, newPath); data.CreateSnapshotData(); participant = new NodeDataParticipant { Data = data, Settings = settings, IsNewNode = isNewNode }; TransactionScope.Participate(participant); if (settings.NodeHead != null) { settings.LastMajorVersionIdBefore = settings.NodeHead.LastMajorVersionId; settings.LastMinorVersionIdBefore = settings.NodeHead.LastMinorVersionId; } int lastMajorVersionId, lastMinorVersionId; DataProvider.Current.SaveNodeData(data, settings, out lastMajorVersionId, out lastMinorVersionId); settings.LastMajorVersionIdAfter = lastMajorVersionId; settings.LastMinorVersionIdAfter = lastMinorVersionId; // here we re-create the node head to insert it into the cache and refresh the version info); if (lastMajorVersionId > 0 || lastMinorVersionId > 0) { var head = NodeHead.CreateFromNode(node, lastMinorVersionId, lastMajorVersionId); if (MustCache(node.NodeType)) { // participate cache items var idKey = CreateNodeHeadIdCacheKey(head.Id); var participant2 = new InsertCacheParticipant { CacheKey = idKey }; TransactionScope.Participate(participant2); var pathKey = CreateNodeHeadPathCacheKey(head.Path); var participant3 = new InsertCacheParticipant { CacheKey = pathKey }; TransactionScope.Participate(participant3); CacheNodeHead(head, idKey, pathKey); } node.RefreshVersionInfo(head); if (!settings.DeletableVersionIds.Contains(node.VersionId)) { // Elevation: we need to create the index document with full // control to avoid field access errors (indexing must be independent // from the current users permissions). using (new SystemAccount()) { indexDocument = SaveIndexDocument(node, true, isNewNode, out hasBinary); } } } if (isLocalTransaction) { TransactionScope.Commit(); } // populate index only if it is enabled on this content (e.g. preview images will be skipped) using (var op2 = SnTrace.Index.StartOperation("Indexing node")) { if (node.IsIndexingEnabled) { using (new SystemAccount()) populator.CommitPopulateNode(populatorData, indexDocument); } if (indexDocument != null && hasBinary) { using (new SystemAccount()) { indexDocument = SaveIndexDocument(node, indexDocument); populator.FinalizeTextExtracting(populatorData, indexDocument); } } op2.Successful = true; } } catch (NodeIsOutOfDateException) { RemoveFromCache(participant); throw; } catch (System.Data.Common.DbException dbe) { if (isLocalTransaction && IsDeadlockException(dbe)) { return(dbe); } throw SavingExceptionHelper(data, dbe); } catch (Exception e) { var ee = SavingExceptionHelper(data, e); if (ee == e) { throw; } else { throw ee; } } finally { if (isLocalTransaction && TransactionScope.IsActive) { TransactionScope.Rollback(); } } op.Successful = true; } return(null); }
private static bool SaveNodeDataTransactional(Node node, NodeSaveSettings settings, IIndexPopulator populator, string originalPath, string newPath) { IndexDocumentData indexDocument = null; bool hasBinary = false; var data = node.Data; var isNewNode = data.Id == 0; NodeDataParticipant participant = null; var isLocalTransaction = !TransactionScope.IsActive; if (isLocalTransaction) { TransactionScope.Begin(); } Logger.WriteVerbose("Transaction: " + TransactionScope.CurrentId + " SAVING " + node.Id + ", " + node.Path); try { //-- collect data for populator var populatorData = populator.BeginPopulateNode(node, settings, originalPath, newPath); data.CreateSnapshotData(); participant = new NodeDataParticipant { Data = data, Settings = settings, IsNewNode = isNewNode }; TransactionScope.Participate(participant); int lastMajorVersionId, lastMinorVersionId; DataProvider.Current.SaveNodeData(data, settings, out lastMajorVersionId, out lastMinorVersionId); //-- here we re-create the node head to insert it into the cache and refresh the version info); if (lastMajorVersionId > 0 || lastMinorVersionId > 0) { var head = NodeHead.CreateFromNode(node, lastMinorVersionId, lastMajorVersionId); if (MustCache(node.NodeType)) { //-- participate cache items var idKey = CreateNodeHeadIdCacheKey(head.Id); var participant2 = new InsertCacheParticipant { CacheKey = idKey }; TransactionScope.Participate(participant2); var pathKey = CreateNodeHeadPathCacheKey(head.Path); var participant3 = new InsertCacheParticipant { CacheKey = pathKey }; TransactionScope.Participate(participant3); CacheNodeHead(head, idKey, pathKey); } node.RefreshVersionInfo(head); if (!settings.DeletableVersionIds.Contains(node.VersionId)) { // Elevation: we need to create the index document with full // control to avoid field access errors (indexing must be independent // from the current users permissions). using (new SystemAccount()) { indexDocument = SaveIndexDocument(node, true, out hasBinary); } } } if (isLocalTransaction) { TransactionScope.Commit(); } //-- populate using (new SystemAccount()) populator.CommitPopulateNode(populatorData, indexDocument); if (indexDocument != null && hasBinary) { using (new SystemAccount()) { indexDocument = SaveIndexDocument(node, indexDocument); populator.FinalizeTextExtracting(populatorData, indexDocument); } } } catch (NodeIsOutOfDateException) { RemoveFromCache(participant); throw; } catch (System.Data.Common.DbException dbe) { Logger.WriteException(new Exception(string.Format("Error saving node. Id: {0}, Path: {1}", node.Id, node.Path), dbe)); if (isLocalTransaction && IsDeadlockException(dbe)) { return(false); } throw SavingExceptionHelper(data, dbe); } catch (Exception e) { Logger.WriteException(new Exception(string.Format("Error saving node. Id: {0}, Path: {1}", node.Id, node.Path), e)); var ee = SavingExceptionHelper(data, e); if (ee == e) { throw; } else { throw ee; } } finally { if (isLocalTransaction && TransactionScope.IsActive) { TransactionScope.Rollback(); } } return(true); }
private static bool SaveNodeDataTransactional(Node node, NodeSaveSettings settings, out IndexDocumentData indexDocument) { indexDocument = null; var data = node.Data; var isNewNode = data.Id == 0; var isLocalTransaction = !TransactionScope.IsActive; if (isLocalTransaction) { TransactionScope.Begin(); } try { data.CreateSnapshotData(); var participant = new NodeDataParticipant { Data = data, Settings = settings, IsNewNode = isNewNode }; TransactionScope.Participate(participant); int lastMajorVersionId, lastMinorVersionId; DataProvider.Current.SaveNodeData(data, settings, out lastMajorVersionId, out lastMinorVersionId); //-- here we re-create the node head to insert it into the cache and refresh the version info if (lastMajorVersionId > 0 || lastMinorVersionId > 0) { var head = NodeHead.CreateFromNode(node, lastMinorVersionId, lastMajorVersionId); if (MustCache(node.NodeType)) { //-- participate cache items var idKey = CreateNodeHeadIdCacheKey(head.Id); var participant2 = new InsertCacheParticipant { CacheKey = idKey }; TransactionScope.Participate(participant2); var pathKey = CreateNodeHeadPathCacheKey(head.Path); var participant3 = new InsertCacheParticipant { CacheKey = pathKey }; TransactionScope.Participate(participant3); CacheNodeHead(head, idKey, pathKey); } node.RefreshVersionInfo(head); if (!settings.DeletableVersionIds.Contains(node.VersionId)) { indexDocument = SaveIndexDocument(node); } } if (isLocalTransaction) { TransactionScope.Commit(); } } catch (System.Data.Common.DbException dbe) { if (isLocalTransaction && IsDeadlockException(dbe)) { return(false); } throw SavingExceptionHelper(data, dbe); } catch (Exception e) { var ee = SavingExceptionHelper(data, e); if (ee == e) { throw; } else { throw ee; } } finally { if (isLocalTransaction && TransactionScope.IsActive) { TransactionScope.Rollback(); } } return(true); }