2011-11-30 7 views
5

Tengo una aplicación utilizada para administrar bases de datos para demos de nuestro software, una de las cosas que hace es obtener una copia de una base de datos de un servidor central y restaurar a una instancia de SQL local. Todo funciona correctamente en la parte de la copia de seguridad, pero en la restauración algunas personas informan que obtienen la siguiente excepción en el medio de la restauración.SMO.Restore.SqlRestore a veces arroja una excepción de tiempo de espera en las computadoras desplegadas

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) 

El MSDN is fairly light sobre el funcionamiento interno de las clases SMO. No pude encontrar ningún método para cambiar el tiempo de espera para ejecutar la restauración. ¿Qué puedo hacer para que la excepción no suceda?


Aquí está el código de realizar la restauración

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

Puede usted Reprod ¿Por esto personalmente? ¿El tamaño de la base de datos es un factor? ¿Hay algún campo binario realmente grande que pueda estar causando esto? ¿El tiempo de espera se produce después de un lapso de tiempo constante? Si realmente está atascado, puede tener un poco de suerte en las asambleas reales usando Reflector para ver cómo funcionan (y replicarlo, probablemente a través de la reflexión (para llegar a miembros privados/internos), con un tiempo de espera mayor). ¿Has visto [esto] (http://stackoverflow.com/q/5979086/21475)? – Cameron

Respuesta

8

Gracias a Cameron sugerencia de la solución a este problema es que necesito fijar ServerConnection.StatementTimeout superior. Aparentemente esto sucede con frecuencia cuando las bases de datos son más grandes que 3GB.

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

U podría usar esto, especialmente cuando no se puede modificar la cadena de conexión o modificación del tiempo de espera en la cadena de conexión no funciona Funciona para mí para una base de datos reflejada más de 2 GB

Utilizando (SqlConnection1)

Dim sqlStmt como secuencia = String.Format ("hoja de BASE DE DATOS backup en disco = '{0}'", backup_directory + 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

Sí, StatementTimeout asigna CommandTimeout; sin embargo, esta pregunta se trataba de utilizar SMO no SqlCommand –

Cuestiones relacionadas