У меня есть метод, который удаляет старые файлы из базы данных в зависимости от некоторых условий:
using (var scope = new TransactionScope(TransactionScopeOption.Required, new System.TimeSpan(0, 15, 0)))
{
using (var ctx = new ElectronicFileEntities())
{
var deleteFilesTime = Int32.Parse(_appSettings["UnFiledDocumentsRetainTime"]);
var cutOffTime = DateTime.Now.AddHours(-deleteFilesTime);
var documentsToDelete = ctx.Documents.Where(o => !o.IsDeleted && !o.IsFiled && o.LastModified < cutOffTime);
foreach (var document in documentsToDelete)
{
_log.InfoFormat("Document to be deleted {0}", document.DocumentId);
document.Comment = "Deleted by loader service - not filed in time";
ctx.DeleteDocument(document.DocumentId, DateTime.Now, 0);
ctx.InsertDocumentHistory(document.DocumentId, "DELETE");
}
ctx.SaveChanges();
}
scope.Complete();
}
Все хорошо в среде UAT, но начал получать ошибки в работе.
Ошибка произошла во время метода: DeleteOldUnFiledDocuments.
Сообщение об ошибке: Ошибка основного провайдера при открытии.
Трассировка стека:
в System.Data.Entity.Core.EntityClient.EntityConnection.Open ()
в System.Data.Entity.Core.Objects.ObjectContext.EnsureConnection (Boolean shouldMonitorTransactions)
в System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction [T] (операция Func 1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass4b.<ExecuteFunction>b__49()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func
1) вSystem.Data.Entity.Core.Objects.ObjectContext.ExecuteFunction (параметры String functionName, ObjectParameter []) в ElectronicFile.Entities.ElectronicCustomerFileEntities.DeleteDocument (Nullable 1 documentId, Nullable
1 lastModified, NullableOnectionObBectionObenceObDectionObenceObDectionObjects, DbB, DЗаключениеОбъединения, повторная попытка обращения,) в System.Data.ProviderBase.DbConnectionFactory.TryGetConnection (DbConnection owningConnection, TaskCompletionSource 1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource
1, повторная попытка, DbConnectionOptions userOptions) в System.Data.SqlClient.SqlConnection.TryOpenInner (TaskCompletionSource 1 retry)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource
1 повтор) в System.Data.SqlClient.SqlConnate.Onity. System.ata.Infrastructure.Interception.InternalDispatcher 1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action
2 операция, TInterceptionContext interceptionContext, действие 3 executing, Action
3 выполнено) в System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.Open (соединение DbConnection, DbInterceptionContext interceptionContextE)..DefaultSqlExecutionStrategy. <> C__DisplayClass1.b__0 () в System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute [TResult] (операция Func`1) в System.Data.Entity.Core.EntityClient.EntityConnection.EntityConnection.
Я думаю, это может быть из-за того, что цикл foreach пытается работать с несколькими записями (Количество удаляемых документов = 7412) Как лучше всего решить эту проблему
Это мой сохраненный рrocedure:
CREATE PROCEDURE [dbo].[DeleteDocument]
@DocumentId INT,
@LastModified DATETIME,
@LastModifiedBy INT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
UPDATE [Document]
SET IsDeleted = 1,
LastModified = @LastModified,
LastModifiedBy = @LastModifiedBy
WHERE
DocumentId = @DocumentId
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
END
Это хранимая процедура для вставки в таблицу истории
CREATE PROCEDURE [dbo].[InsertDocumentHistory]
@DocumentId INT,
@ChangeType VARCHAR(10)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
DECLARE @ChangeDateTime AS DATETIME
SELECT @ChangeDateTime = LastModified
FROM [Document]
WHERE DocumentId = @DocumentId
UPDATE DocumentHistory
SET ActiveTo = @ChangeDateTime
WHERE DocumentId = @DocumentId
AND ActiveTo IS NULL
INSERT INTO DocumentHistory (DocumentId, DocumentTypeId, InTrayId, CustomerFileId, ReferenceId,
FileDataId, FileDataType, FileDataSize, FileNoteReference,
EffectiveStartDate, EffectiveEndDate, Comment, OriginalFileName,
IsFiled, IsFlatten, IsVerified, IsDeleted,
ExternalPartyId, ExternalPartyTypeId,
ChangeBy, ChangeType, ActiveFrom)
SELECT
DocumentId, DocumentTypeId, InTrayId, CustomerFileId, ReferenceId,
FileDataId, FileDataType, FileDataSize, FileNoteReference,
EffectiveStartDate, EffectiveEndDate, Comment, OriginalFileName,
IsFiled, IsFlatten, IsVerified, IsDeleted,
ExternalPartyId, ExternalPartyTypeId, LastModifiedBy,
@ChangeType, @ChangeDateTime
FROM
[Document]
WHERE
DocumentId = @DocumentId
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
END