Подтвердить что ты не робот

Как писать большие файлы на SQL Server FILESTREAM?

У меня возникла проблема с записью больших объемов данных в столбец FILESTREAM на SQL Server. В частности, небольшие файлы размером около 1,5-2 ГБ обрабатываются отлично, но когда размер достигает 6 ГБ и выше, я получаю прерывистый IOException "Ручка недействительна" на .CopyTo() ближе к концу передачи.

Я думал о написании данных в кусках, но SQL Server копирует файл резервной копии для поля, прежде чем разрешить добавлять к нему данные, что полностью разрушает производительность для больших файлов.

Здесь код:

public long AddFragment (string location , string description = null) 
{
    const string sql = 
        @"insert into [Fragment] ([Description],[Data]) " +
            "values (@description,0x); " +
         "select [Id], [Data].PathName(), " +
             "GET_FILESTREAM_TRANSACTION_CONTEXT() " +
         "from " +
             "[Fragment] " +
         "where " +
             "[Id] = SCOPE_IDENTITY();";

    long id;

    using (var scope = new TransactionScope(
        TransactionScopeOption.Required, 
            new TransactionOptions {
                Timeout = TimeSpan.FromDays(1)
            })) 
    {
        using (var connection = new SqlConnection(m_ConnectionString)) 
        {
            connection.Open();

            byte[] serverTx;
            string serverLocation;

            using (var command = new SqlCommand (sql, connection)) 
            {
                command.Parameters.Add("@description", 
                    SqlDbType.NVarChar).Value = description;

                using (var reader = command.ExecuteReader ()) 
                {
                    reader.Read();
                    id = reader.GetSqlInt64(0).Value;
                    serverLocation = reader.GetSqlString (1).Value;
                    serverTx = reader.GetSqlBinary (2).Value;
                }
            }

            using (var source = new FileStream(location, FileMode.Open, 
                FileAccess.Read, FileShare.Read, 4096, 
                FileOptions.SequentialScan))
            using (var target = new SqlFileStream(serverLocation, 
                serverTx, FileAccess.Write))
            {
                source.CopyTo ( target );
            }
        }

        scope.Complete();
    }

    return id;
}
4b9b3361

Ответ 2

Как было предложено некоторыми комментариями, проблема, вероятно, является таймаутом транзакции. Вы можете проверить это, запустив SQL Server Profiler и наблюдая за откатом транзакции.

Если не указано иное, machine.config имеет значение maxTimeout по умолчанию 10 минут, которое нельзя переопределить с помощью кода. Чтобы увеличить максимальное время ожидания, добавьте следующее в настройку конфигурации вашего machine.config

<system.transactions>
  <machineSettings maxTimeout="00:30:00" />
</system.transactions>