2011-11-30 8 views
5

Mam aplikację służącą do zarządzania bazami danych dla wersji demonstracyjnych naszego oprogramowania. Jedną z rzeczy, którą robi, jest pobranie kopii bazy danych z centralnego serwera i przywrócenie do lokalnej instancji SQL. Wszystko działa poprawnie na części kopii zapasowej, ale po przywróceniu niektórzy ludzie zgłaszają, że otrzymali następujący wyjątek w środku przywracania.SMO.Restore.SqlRestore czasami zgłasza wyjątek timeout na wdrożonych komputerach

Microsoft.SqlServer.Management.Smo.FailedOperationException: Restore failed for Server 'Computername'. 
---> Microsoft.SqlServer.Management.Common.ExecutionFailureException: 
    An exception occurred while executing a Transact-SQL statement or batch. 
    ---> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 
      at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) 
      (snip) 
      at Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType) 
     --- End of inner exception stack trace --- 
     at Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType) 
     (snip) 
     at Microsoft.SqlServer.Management.Smo.Restore.SqlRestore(Server srv) 
--- End of inner exception stack trace --- 
at Microsoft.SqlServer.Management.Smo.Restore.SqlRestore(Server srv) 
at ContractFlowTool.WebInfinity2.AttachDatabase.RestoreLocal(AttachDatabaseArgs arg) 

The MSDN is fairly light o wewnętrznej pracy klas SMO. Nie mogłem znaleźć żadnej metody zmiany czasu oczekiwania na wykonanie przywracania. Co mogę zrobić, aby wyjątek się nie wydarzył?


Oto kod wykonaniem przywracania

private static bool RestoreLocal(AttachDatabaseArgs arg) 
{ 
    if (arg.DestDatabase == null) 
     throw new ArgumentNullException("DestDatabase"); 
    SqlConnectionInfo serverConnInfo = new SqlConnectionInfo(/*snip*/); 
    ServerConnection serverConn = null; 
    serverConn = new ServerConnection(serverConnInfo); 
    var remoteServer = new Server(serverConn); 
    var clinicFolder = ClinicFolder(arg); 
    var restore = new Restore(); 
    restore.PercentCompleteNotification = 5; 
    restore.NoRecovery = false; 
    restore.RelocateFiles.Add(/*snip mdf*/); 
    restore.RelocateFiles.Add(/*snip ldf*/); 
    restore.Database = arg.LocalDB; 
    restore.ReplaceDatabase = true; 
    restore.Action = RestoreActionType.Database; 
    restore.PercentComplete += arg.ProgressForm.Restore_PercentComplete; 

    restore.SqlRestore(remoteServer); 
} 
+0

Możesz Reprod Czy to osobiście? Czy rozmiar bazy danych jest czynnikiem? Czy istnieją naprawdę duże pola binarne, które mogą być przyczyną tego? Czy limit czasu występuje po upływie określonego czasu? Jeśli naprawdę utkniesz, możesz mieć trochę szczęścia wkopując się w rzeczywiste zgromadzenia za pomocą Reflectora, aby zobaczyć, jak działają (i replikować je, prawdopodobnie poprzez odbicie (aby dostać się do prywatnych/wewnętrznych członków), z wyższym czasem oczekiwania). Widziałeś [to] (http://stackoverflow.com/q/5979086/21475)? – Cameron

Odpowiedz

8

Dzięki Camerons sugestią rozwiązaniem tego problemu było to, że muszę ustawić ServerConnection.StatementTimeout wyższa. Najwyraźniej dzieje się tak często, gdy bazy danych są większe niż 3 GB.

(...) 
serverConn = new ServerConnection(serverConnInfo); 
serverConn.StatementTimeout = 240; //<- set this. 
var remoteServer = new Server(serverConn); 
var clinicFolder = ClinicFolder(arg); 
(...) 
0

U mógłby to wykorzystać, szczególnie, gdy nie można zmodyfikować ciąg połączenia lub modyfikację limitu czasu w ciągu połączenia nie działa To działa dla mnie lustrzanej bazy ponad 2 GB

użyciu (sqlConnection1)

Dim sqlStmt As String = String.Format ("kopia zapasowa bazy danych map na dysk = '{0}'", katalog_kopii_zapasowej + BackupFile)

  Using bu2 As New SqlCommand(sqlStmt, SqlConnection1) 
       SqlConnection1.Open() 
       bu2.CommandTimeout = 180 //this line is the key 
       bu2.ExecuteNonQuery() 
       SqlConnection1.Close() 
      End Using 
     End Using 
+1

Tak, StatementTimeout mapuje CommandTimeout, jednak to pytanie dotyczyło użycia SMO, a nie SqlCommand –

Powiązane problemy