2015-04-12 181 views
2

問題大批量插入引起事務中止或超時

在做有幾十萬行的批量插入了兩個數據庫(以編程方式,相同的情況下,相同的模式)和每個數據庫約17桌,我幾乎總是會收到Transcaction異常終止或超時過期異常。

如何

使用的EntityFramework 6的數據情況下,我在數據庫上運行一個SqlCommand。

using (var tran = new TransactionScope(TransactionScopeOption.Required, transactionOptions)) 
{ 
    context.Database.ExecuteSqlCommand(
     "BULK INSERT " + table + 
     " FROM '" + Directory + 
     table + ".csv' WITH (DATAFILETYPE = 'widechar', FIRSTROW = 2, FIELDTERMINATOR = '[TERM]', ERRORFILE = '" + 
     Logfile + DateTime.Now.ToString(@"yyyy-MM-dd") + "-R" + DateTime.Now.Second + DateTime.Now.Millisecond + 
     ".txt', ROWTERMINATOR = '\n', KEEPNULLS, TABLOCK)"); 

    tran.Complete(); 
} 

設置超時值

爲了打擊我一直面臨着我同時設置命令和事務超時在8分鐘的問題。任何異常都會在所述十八分鐘過去之前發生。

context.Database.CommandTimeout = 1080; 
TransactionOptions transactionOptions = new TransactionOptions(); 
transactionOptions.Timeout = TimeSpan.FromMinutes(18); 

全部例外

System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out 
    at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
    at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 
    at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 
    at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite) 
    at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) 
    at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 
    at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c) 
    at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) 
    at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext) 
    at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery() 
    at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass59.<ExecuteStoreCommand>b__58() 
    at 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__DisplayClass59.<ExecuteStoreCommand>b__57() 
    at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) 
    at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreCommand(TransactionalBehavior transactionalBehavior, String commandText, Object[] parameters) 
    at System.Data.Entity.Internal.InternalContext.ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, String sql, Object[] parameters) 
    at System.Data.Entity.Database.ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, String sql, Object[] parameters) 
    at System.Data.Entity.Database.ExecuteSqlCommand(String sql, Object[] parameters) 
    at MyProject.Updaters.MSSQL.Csv.ImportCsvFiles() in c:\Users\MyUser\Desktop\MyProject2\XMLtoDBcron\Updaters\MSSQL\Csv.cs:line 48 
ClientConnectionId:fef47d9c-3e13-444f-939b-f9bd570abb36 

+

System.Transactions.TransactionAbortedException: The transaction has aborted. ---> System.TimeoutException: Transaction Timeout 
    --- End of inner exception stack trace --- 
    at System.Transactions.TransactionStateAborted.BeginCommit(InternalTransaction tx, Boolean asyncCommit, AsyncCallback asyncCallback, Object asyncState) 
    at System.Transactions.CommittableTransaction.Commit() 
    at System.Transactions.TransactionScope.InternalDispose() 
    at System.Transactions.TransactionScope.Dispose() 
    at MyProject.Updaters.MSSQL.Csv.InsertCsvData() in c:\Users\MyUser\Desktop\MyProject2\XMLtoDBcron\Updaters\MSSQL\Csv.cs:line 109 
    at MyProject.Updaters.MSSQL.Csv.ImportCsvFiles() in c:\Users\MyUser\Desktop\MyProject2\XMLtoDBcron\Updaters\MSSQL\Csv.cs:line 74 

怎麼辦

我找不到在SQL Server中類似的任何設置或(使用SSMS )。您將請求幫助提供答案的任何額外數據。

回答

1

有關SQL過程中timout命令的執行,我會建議您設置的CommandTimeout通過的ObjectContext中的DbContext包裹:

((IObjectContextAdapter)context).ObjectContext.CommandTimeout = 1080; 

這種做法一直爲我工作。