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);
}