Rollback() public static méthode

Rollbacks the current transaction.
public static Rollback ( ) : void
Résultat void
        /// <summary>
        /// Marks orphaned file records (the ones that do not have a referencing binary record anymore) as Deleted.
        /// </summary>
        public void CleanupFilesSetDeleteFlag()
        {
            var isLocalTransaction = false;

            if (!TransactionScope.IsActive)
            {
                TransactionScope.Begin();
                isLocalTransaction = true;
            }

            try
            {
                using (var proc = new SqlProcedure {
                    CommandText = CleanupFileSetIsdeletedScript, CommandType = CommandType.Text
                })
                {
                    proc.CommandType = CommandType.Text;
                    proc.ExecuteNonQuery();
                }

                if (isLocalTransaction && TransactionScope.IsActive)
                {
                    TransactionScope.Commit();
                }
            }
            catch (Exception ex)
            {
                if (isLocalTransaction && TransactionScope.IsActive)
                {
                    TransactionScope.Rollback();
                }

                throw new DataException("Error during setting deleted flag on files.", ex);
            }
        }
        /// <summary>
        /// Finalizes a chunked save operation.
        /// </summary>
        /// <param name="versionId">Content version id.</param>
        /// <param name="propertyTypeId">Binary property type id.</param>
        /// <param name="fileId">File identifier.</param>
        /// <param name="fullSize">Full size (stream length) of the binary value.</param>
        /// <param name="source">Binary data containing metadata (e.g. content type).</param>
        public void CommitChunk(int versionId, int propertyTypeId, int fileId, long fullSize, BinaryDataValue source = null)
        {
            // start a new transaction here if needed
            var isLocalTransaction = !TransactionScope.IsActive;

            if (isLocalTransaction)
            {
                TransactionScope.Begin();
            }

            try
            {
                // commit the process: set the final full size and checksum
                using (var cmd = new SqlProcedure {
                    CommandText = CommitChunkScript, CommandType = CommandType.Text
                })
                {
                    cmd.Parameters.Add("@FileId", SqlDbType.Int).Value            = fileId;
                    cmd.Parameters.Add("@VersionId", SqlDbType.Int).Value         = versionId;
                    cmd.Parameters.Add("@PropertyTypeId", SqlDbType.Int).Value    = propertyTypeId;
                    cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value           = fullSize;
                    cmd.Parameters.Add("@Checksum", SqlDbType.VarChar, 200).Value = DBNull.Value;

                    cmd.Parameters.Add("@ContentType", SqlDbType.NVarChar, 50).Value = source != null ? source.ContentType : string.Empty;
                    cmd.Parameters.Add("@FileNameWithoutExtension", SqlDbType.NVarChar, 450).Value = source != null
                        ? source.FileName.FileNameWithoutExtension == null
                            ? DBNull.Value
                            : (object)source.FileName.FileNameWithoutExtension
                        : DBNull.Value;

                    cmd.Parameters.Add("@Extension", SqlDbType.NVarChar, 50).Value = source != null?ValidateExtension(source.FileName.Extension) : string.Empty;

                    cmd.ExecuteNonQuery();
                }
            }
            catch (Exception ex)
            {
                // rollback the transaction if it was opened locally
                if (isLocalTransaction && TransactionScope.IsActive)
                {
                    TransactionScope.Rollback();
                }

                throw new DataException("Error during committing binary chunk to file stream.", ex);
            }
            finally
            {
                // commit the transaction if it was opened locally
                if (isLocalTransaction && TransactionScope.IsActive)
                {
                    TransactionScope.Commit();
                }
            }
        }
Exemple #3
0
        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);
        }
        /// <summary>
        /// Starts a chunked save operation on an existing content. It does not write any binary data
        /// to the storage, it only makes prerequisite operations - e.g. allocates a new slot in the storage.
        /// </summary>
        /// <param name="blobProvider">Blob storage provider.</param>
        /// <param name="versionId">Content version id.</param>
        /// <param name="propertyTypeId">Binary property type id.</param>
        /// <param name="fullSize">Full size (stream length) of the binary value.</param>
        /// <returns>A token containing all the information (db record ids) that identify a single entry in the blob storage.</returns>
        public string StartChunk(IBlobProvider blobProvider, int versionId, int propertyTypeId, long fullSize)
        {
            var isLocalTransaction = !TransactionScope.IsActive;

            if (isLocalTransaction)
            {
                TransactionScope.Begin();
            }

            var ctx = new BlobStorageContext(blobProvider)
            {
                VersionId = versionId, PropertyTypeId = propertyTypeId, FileId = 0, Length = fullSize
            };
            string blobProviderName = null;
            string blobProviderData = null;
            bool   useSqlFileStream;

            if (IsBuiltInOrSqlFileStreamProvider(blobProvider))
            {
                useSqlFileStream = SqlFileStreamBlobProvider.UseFileStream(blobProvider, fullSize);
            }
            else
            {
                useSqlFileStream = false;
                blobProvider.Allocate(ctx);
                blobProviderName = blobProvider.GetType().FullName;
                blobProviderData = BlobStorageContext.SerializeBlobProviderData(ctx.BlobProviderData);
            }

            try
            {
                using (var cmd = new SqlProcedure {
                    CommandText = InsertStagingBinaryScript, CommandType = CommandType.Text
                })
                {
                    cmd.Parameters.Add("@VersionId", SqlDbType.Int).Value              = versionId;
                    cmd.Parameters.Add("@PropertyTypeId", SqlDbType.Int).Value         = propertyTypeId;
                    cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value                = fullSize;
                    cmd.Parameters.Add("@UseSqlFileStream", SqlDbType.TinyInt).Value   = useSqlFileStream ? 2 : 0;
                    cmd.Parameters.Add("@BlobProvider", SqlDbType.NVarChar, 450).Value = blobProviderName != null ? (object)blobProviderName : DBNull.Value;
                    cmd.Parameters.Add("@BlobProviderData", SqlDbType.NVarChar, int.MaxValue).Value = blobProviderData != null ? (object)blobProviderData : DBNull.Value;

                    int binaryPropertyId;
                    int fileId;

                    using (var reader = cmd.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            binaryPropertyId = reader.GetSafeInt32(0);
                            fileId           = reader.GetSafeInt32(1);
                        }
                        else
                        {
                            throw new DataException("File row could not be inserted.");
                        }
                    }

                    ctx.FileId = fileId;

                    return(new ChunkToken
                    {
                        VersionId = versionId,
                        PropertyTypeId = propertyTypeId,
                        BinaryPropertyId = binaryPropertyId,
                        FileId = fileId
                    }.GetToken());
                }
            }
            catch (Exception ex)
            {
                if (isLocalTransaction && TransactionScope.IsActive)
                {
                    TransactionScope.Rollback();
                }

                throw new DataException("Error during saving binary chunk to SQL Server.", ex);
            }
            finally
            {
                if (isLocalTransaction && TransactionScope.IsActive)
                {
                    TransactionScope.Commit();
                }
            }
        }
        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);
        }