2010-02-28 7 views
5

próbuję wykonać następujące czynności:Próbując oderwać dołączyć bazę danych - nie mogą Acces db po

  • odłączyć bazę

  • Kopiowanie plików do folderu tymczasowego

  • Dołączanie bazy danych ponownie

To działa po raz pierwszy, ale kiedy ja tr y do uruchomienia tej metody po raz drugi z tego samego procesu pojawia się błąd. Zawsze mogę uzyskać dostęp do bazy danych, która została dołączona ponownie od innych klientów, ale nie z poziomu mojej aplikacji.

Błąd jest:

„błąd poziomu transportu podczas próby wysłania żądania do serwera. (Dostawca: Shared Memory-Provider, błąd:. 0 - brak proces na drugim końcu rury)” , kiedy próbuję odczytać dane z pliku sys.database_files z nowo dołączonego db.

Błąd jest tłumaczone z niemieckiego "Fehler beim auf Übertragungsebene Senden der Anforderung Serwera den".

Zdarza się po "cmdGetDBFileName.ExecuteReader". Nadal mogę otworzyć połączenie, ale wysyłam kwerendę do błędów sys.database_files.

Źródło jest dość długie, ale domyślam się, że możesz pominąć część na początku, w której otrzymam nazwy plików db do oderwania. Czy widzisz mój błąd lub masz jakieś pomysły, co mogę sprawdzić?

public bool DetachB2CPrepare() 
     { 
      _log.Debug("DetachB2CPrepare"); 
      SqlConnection prepareDBConnection = null; 
      SqlConnection prepareMasterDBConnection = null; 
      SqlDataReader readerDbFiles = null; 

      bool result = true; 
      try 
      { 
       //rc_b2c_product_prepare.mdf  
       string prepareDBPysicalFileName = ""; 
       //rc_b2c_product_prepare  
       string prepareDBFileName = ""; 
       //D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\rc_b2c_product_prepare.mdf 
       string prepareDBFileNameComplete = ""; 

       //rc_b2c_product_prepare_1.ldf 
       string prepareTransactionLogPhysicalFileName = ""; 
       //rc_b2c_product_prepare_log  
       string prepareTransactionLogFileName = ""; 
       //D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\rc_b2c_product_prepare_1.ldf 
       string prepareTransactionLogFileNameComplete = ""; 
       _log.DebugFormat("Try to open B2CPrepare"); 
       prepareDBConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["B2CPrepare"].ConnectionString); 
       prepareDBConnection.Open(); 



       //Get the file names of DB 
       SqlCommand cmdGetDBFileName = new SqlCommand("select name , physical_name, type from sys.database_files where type= 0"); 
       cmdGetDBFileName.Connection = prepareDBConnection; 
       readerDbFiles = cmdGetDBFileName.ExecuteReader(); 
       if (readerDbFiles.Read()) 
       { 
        prepareDBFileName = (string)readerDbFiles["name"]; 
        prepareDBFileNameComplete = (string)readerDbFiles["physical_name"]; 
        int lastSlash = prepareDBFileNameComplete.LastIndexOf(@"\"); 
        prepareDBPysicalFileName = prepareDBFileNameComplete.Substring(lastSlash + 1, prepareDBFileNameComplete.Length - lastSlash - 1); 
        readerDbFiles.Close(); 
       } 
       else{ 
        return false; 
       } 

       cmdGetDBFileName.CommandText = "select name , physical_name, type from sys.database_files where type= 1"; 
       readerDbFiles = cmdGetDBFileName.ExecuteReader(); 
       if (readerDbFiles.Read()) 
       { 
        prepareTransactionLogFileName = (string)readerDbFiles["name"]; 
        prepareTransactionLogFileNameComplete = (string)readerDbFiles["physical_name"]; 
        int lastSlash = prepareTransactionLogFileNameComplete.LastIndexOf(@"\"); 
        prepareTransactionLogPhysicalFileName = prepareTransactionLogFileNameComplete.Substring(lastSlash + 1, prepareTransactionLogFileNameComplete.Length - lastSlash - 1); 
        readerDbFiles.Close(); 
       } 
       else 
       { 
        return false; 
       } 

       _log.DebugFormat("shrink transactionlog {0}", prepareTransactionLogFileName); 

       SqlCommand cmdShrinkPrepare = new SqlCommand(string.Format(@"DBCC Shrinkfile('{0}',100) ", prepareTransactionLogFileName)); 
       cmdShrinkPrepare.Connection = prepareDBConnection; 
       cmdShrinkPrepare.ExecuteNonQuery(); 

       //master auf MyProductName 
       prepareMasterDBConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyProductNameMaster"].ConnectionString); 
       prepareMasterDBConnection.Open(); 

       _log.Debug("cmdOffline"); 

       //Datenbank verbindunge löschen 
       SqlCommand cmdOffline = new SqlCommand(@"ALTER DATABASE rc_b2c_product_prepare SET SINGLE_USER WITH ROLLBACK IMMEDIATE"); 
       cmdOffline.Connection = prepareMasterDBConnection; 
       cmdOffline.ExecuteNonQuery(); 

       _log.Debug("cmdDetach: rc_b2c_product_prepare" ); 

       SqlCommand cmdDetach = new SqlCommand(@"dbo.sp_detach_db @dbname = N'rc_b2c_product_prepare',@keepfulltextindexfile = N'false'"); 
       cmdDetach.Connection = prepareMasterDBConnection; 
       cmdDetach.ExecuteNonQuery(); 

       string pathForCopies = MyProductName.Backend.settings.B2CPrepareDBBackupPath; 

       //copy files to temp folder 
       string tempFileDB = pathForCopies + "\\" + prepareDBPysicalFileName; 
       string tempFileLog = pathForCopies + "\\" + prepareTransactionLogPhysicalFileName; 

       _log.DebugFormat("Copy: {0} TO: {1}", prepareDBFileNameComplete, tempFileDB); 

       System.IO.File.Copy(prepareDBFileNameComplete, tempFileDB, true); 

       _log.DebugFormat("Copy: {0} TO: {1}", prepareTransactionLogFileNameComplete, tempFileLog); 

       System.IO.File.Copy(prepareTransactionLogFileNameComplete, tempFileLog, true); 

       _log.DebugFormat("cmdAttach: db {0} log {1}", prepareDBFileNameComplete, prepareTransactionLogFileNameComplete); 

       SqlCommand cmdAttach = new SqlCommand( 
         string.Format(@" 
         CREATE DATABASE rc_b2c_product_prepare ON 
         (FILENAME = N'{0}'), 
         (FILENAME = N'{1}') 
         FOR ATTACH", prepareDBFileNameComplete, prepareTransactionLogFileNameComplete)); 

       cmdAttach.Connection = prepareMasterDBConnection; 
       cmdAttach.ExecuteNonQuery(); 

       _log.Debug("ALTER DATABASE rc_b2c_product_prepare SET MULTI_USER "); 

       //set multi user 
       SqlCommand cmdOnline = new SqlCommand(@"ALTER DATABASE rc_b2c_product_prepare SET MULTI_USER WITH ROLLBACK IMMEDIATE"); 
       cmdOnline.Connection = prepareMasterDBConnection; 
       cmdOnline.ExecuteNonQuery(); 

       return result; 
      } 
      catch (Exception e) 
      { 
       _log.Error(e); 
       return false; 
      } 
      finally 
      { 
       if (prepareDBConnection != null) 
       { 
        prepareDBConnection.Close(); 
       } 
       if (prepareMasterDBConnection != null) 
       { 
        prepareMasterDBConnection.Close(); 
       } 
       if (readerDbFiles != null) 
       { 
        readerDbFiles.Close(); 
       } 
      } 
     } 

Odpowiedz

1

Wygląda na to, że może to być związane z próbą użycia połączenia, które nie jest już ważne z powodu łączenia połączeń.

Można spróbować wyłączyć buforowanie połączeń, aby sprawdzić, czy to jest problem. Aby to zrobić, dodaj "Pooling = false" do ciągu połączenia SQL w pliku konfiguracyjnym.

+0

wyłączenie połączenia ppoiling doszło do sztuczki –

1

Może być problem z puli połączeń, czy próbowałeś zamykając prepareDBConnection przed wykonaniem odłączyć/podłączyć?

Po drugie, czy spojrzałeś na obiekty zarządzania SQL (SMO) - tutaj jest example for the detach/attach.

Po trzecie, nie musisz odłączać bazy danych, gdy chcesz tylko wykonać kopię zapasową, możesz ustawić ją w trybie offline. Using SMO lub using SQL (sp_dboption doc).

0

Aby odłączyć bazę danych MSSQL

USE master; 
GO 
ALTER DATABASE [AdventureWorks2012] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; 
EXEC sp_detach_db @dbname = N'AdventureWorks2012'; 
GO 

Aby dołączyć jednorodzinnego baza danych,

USE master; 
GO 
CREATE DATABASE MyAdventureWorks 
ON (FILENAME = 'C:\MySQLServer\AdventureWorks2012_Data.mdf'), 
(FILENAME = 'C:\MySQLServer\AdventureWorks2012_Log.ldf') 
FOR ATTACH; 
GO 

Próbowałem tego kodu dla wielu baz danych, to działało w porządku.