2012-02-08 50 views
5

我寫了一個非常小的C#程序,使用非常小的SQL Server數據庫,純粹是爲了一些學習&測試目的。數據庫被用在這個新的項目中,而不是其他地方。但是,我在運行程序無法運行的調試時遇到問題,因爲數據庫「正在被另一個進程使用」。數據庫正在被另一個進程使用......但是什麼進程?

如果我重新啓動我的機器,它會重新工作,然後幾個測試運行後,我會再次得到了同樣的問題。

我發現報道在互聯網上很多很多類似的問題,但找不到任何明確的答案如何解決這個問題。首先,如何找出使用我的.mdf & .ldf文件的「其他進程」?那麼,我怎麼才能讓這些不被髮布的文件發佈,以便一次又一次地阻止這種發生的時間?!?

我是新來的VS2010,SQL服務器& C#,所以請你給我任何答覆相當的描述!

這是我的代碼,正如你所看到的,你不能得到任何更基本的東西,我當然不應該遇到這麼多問題!

namespace MySqlTest 
{ 
    public partial class Form1 : Form 
    { 
     SqlConnection myDB = new SqlConnection(@"Data Source=MEDESKTOP;AttachDbFilename=|DataDirectory|\SqlTestDB.mdf;Initial Catalog=MySqlDB;Integrated Security=True"); 
     SqlDataAdapter myDA = new SqlDataAdapter(); 
     SqlCommand mySqlCmd = new SqlCommand(); 

     string mySQLcmd; 
     int myCount; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      MessageBox.Show("myDB state = " + myDB.State.ToString()); 
      //Open SQL File 
      myDB.Open(); 
      MessageBox.Show("myDB state = " + myDB.State.ToString()); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      myCount++; 
      MessageBox.Show("myCount = " + myCount.ToString()); 
      //Insert Record Into SQL File 
      mySqlCmd.Connection = myDB; 
      mySqlCmd.CommandText = "INSERT INTO Parent(ParentName) Values(myCount)"; 
      myDA = new SqlDataAdapter(mySqlCmd); 
      mySqlCmd.ExecuteNonQuery(); 
     } 

     private void button3_Click(object sender, EventArgs e) 
     { 
      //Read Record From SQL File 
     } 

     private void button4_Click(object sender, EventArgs e) 
     { 
      //Read All Records From SQL File 
     } 

     private void button5_Click(object sender, EventArgs e) 
     { 
      //Delete Record From DQL File 
     } 

     private void button6_Click(object sender, EventArgs e) 
     { 
      MessageBox.Show("myDB state = " + myDB.State.ToString()); 
      //Close SQL File 
      myDB.Close(); 
      MessageBox.Show("myDB state = " + myDB.State.ToString()); 
     } 

     private void button7_Click(object sender, EventArgs e) 
     { 
      //Quit 
      this.Close(); 
     } 
    } 
} 
+0

第一次運行應用程序時是否收到相同的錯誤消息?如果第二次出現此錯誤,我猜你的應用程序沒有正確關閉數據庫連接。 – 2012-02-08 14:45:47

+1

當我第一次運行程序時,它工作正常,並繼續工作,但我正在調試並停止程序,而沒有按時邏輯地完成它。雖然沒有出現這種情況,但它可能與我在不關閉數據庫的情況下停止調試有關。雖然VS2010不會處理?!? – 2012-02-08 14:56:43

回答

6

最有可能的選擇:

  1. 先前的(崩潰)程序
  2. Visual Studio中的實例(用表設計器中打開或類似的東西)

你可以檢查1)與TaskManager和2)通過查看服務器瀏覽器。你的數據庫應該顯示一個小紅叉,意思是「關閉」。

你應該重寫代碼,以儘快關閉連接。使用try/finally或using(){ }塊。

+0

那麼,關於重寫我的代碼,這就是這個小程序的原因,以便我可以確定爲我編寫我的SQL-Server處理程序以用於我的真實程序的最佳方式!在Seerver Explorer中,我的數據庫有紅叉,但我仍然收到錯誤消息。 – 2012-02-08 14:59:11

0

嘗試運行sp_who2看到進程的列表。

FYI:您不需要重新啓動計算機,最壞的情況下,重新啓動SQL Server服務

+0

我會稍微嘗試一下,現在必須收集學校的孩子們......如果你是正確的,那將會爲我節省很多時間! – 2012-02-08 15:01:04

+0

好吧,讓我們知道:) – Diego 2012-02-08 15:09:52

+0

好吧,VS2010不會讓我打開一個新的查詢,它說:「無法打開物理文件.....操作系統錯誤32:」32(無法檢索此文本錯誤原因:15105)。嘗試爲文件附加一個自動命名的數據庫.....失敗。名稱相同的數據庫存在,或者指定的文件無法打開,或者它位於UNC共享上「,所以我在SQL Server Management Studio中運行了sp_who2並獲得了31個結果,其中只有最底層的2個似乎與此數據庫相關,即它們在DBName列中有MySqlDB。 – 2012-02-08 16:37:01

0

IIRC使用AttachDbFilename旋轉了SqlServr.exe過程中的用戶帳戶下運行的過程是使用從SQLServer的實例分開作爲服務運行(因此停止MsSqlServer服務不會阻止此問題)。在骯髒退出的情況下,有時這個過程不會被清理乾淨。我懷疑殺死這個過程會釋放數據庫文件。

+0

根據我下面的回覆,殺死進程,迄今爲止,沒有幫助...... – 2012-02-08 17:37:20

+0

我必須進入服務和查找MSSQLSERVER,更改開始選項爲手動,然後在物理上停止它......只有這樣,才能刪除bin \ debug文件夾中的文件!我將開始選項改回自動&開始服務,並且最後它再次工作!現在我必須找出它爲什麼會發生,並防止它再次發生... – 2012-02-08 18:41:45

0

嘗試使用由Microsoft的技術研究員Mark Russinovich編寫的Process Explorer。這是Windows管理員/開發人員口袋裏的標準瑞士軍隊工具。它可以顯示系統中哪些進程正在處理資源句柄。

一旦你安裝了進程資源管理器,請嘗試以下操作:

  1. 讓你的系統進入故障狀態(使得運行程序不工作)。
  2. 啓動Process Explorer(您需要成爲Admin以充分利用其功能)。
  3. 點擊頂部菜單欄中的「查找」,然後輸入.mdf或.ldf文件的名稱。

搜索結果應該顯示一個進程/服務,其中一個資源仍由一個錯誤終止的進程持有。

+0

它找到LDF文件,但根據我對迭戈(上圖)的回覆,不會釋放它:-(!!! – 2012-02-08 17:32:35

+0

我必須進入服務和查找MSSQLSERVER,將開始選項更改爲手動,然後物理停止它...只有然後,我能夠刪除bin \ debug文件夾中的文件!!!我改變了開始選項返回到自動&開始服務,並且最後,它是所有工作再次!!!現在我必須找出它爲什麼發生並且防止它再發生... – 2012-02-08 18:41:37

1

這是重寫的代碼,使用「使用」語句。當我執行程序並單擊將記錄插入SQL文件時,將其關閉,完成myCount = 1的過程(雖然我不是100%確定它實際上是在進行物理寫入,但我是否錯過了一個命令「提交」更新?!?)並重新顯示錶單。

如果我再點擊插入記錄到SQL文件再次,我得到一個錯誤如下:

SqlException was unhandled

Cannot open user default database. Login failed. Login failed for user 'MEDESKTOP\Gary'.

這是程序(我這臺電腦上的唯一用戶,並有完整的管理權,在這一點上數據庫的「國家」,根據屬性,封閉的,所以它看起來像第一次通過代碼沒有象預期的那樣......

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Data.SqlClient; 

namespace MySqlTest 
{ 
public partial class Form1 : Form 
{ 
    int myCount; 
    string myDBlocation = @"Data Source=MEDESKTOP;AttachDbFilename=|DataDirectory|\mySQLtest.mdf;Integrated Security=True;User Instance=False"; 

    public Form1() 
    { 
     InitializeComponent(); 

    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     myCount++; 
     MessageBox.Show("myCount = " + myCount.ToString()); 
     //Insert Record Into SQL File 
     myDB_Insert(); 
    } 

    private void button3_Click(object sender, EventArgs e) 
    { 
     //Read Record From SQL File 

    } 

    private void button4_Click(object sender, EventArgs e) 
    { 
     //Read All Records From SQL File 

    } 

    private void button5_Click(object sender, EventArgs e) 
    { 
     //Delete Record From SQL File 
    } 

    private void button7_Click(object sender, EventArgs e) 
    { 
     //Quit 
     myDB_Close(); 
     this.Close(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 

    } 

    private void Form1_Close(object sender, EventArgs e) 
    { 

    } 

    void myDB_Insert() 
    { 
     using (SqlConnection myDB = new SqlConnection(myDBlocation)) 
     using (SqlCommand mySqlCmd = myDB.CreateCommand()) 
     { 
      myDB.Open(); **<<< Program fails here, 2nd time through** 
      mySqlCmd.CommandText = "INSERT INTO Parent (ParentName) VALUES(@ParentNameValue)"; 
      mySqlCmd.Parameters.AddWithValue("@ParentNameValue", myCount); 
      mySqlCmd.ExecuteNonQuery(); 
      myDB.Close(); 
     } 
     return; 
    } 

    void myDB_Close() 
    { 
     using (SqlConnection myDB = new SqlConnection(myDBlocation)) 
     using (SqlCommand mySqlCmd = new SqlCommand()) 
     { 
      myDB.Close(); 
     } 
     return; 
    } 

} 
} 

我不明白爲什麼我突然無法訪問我已經使用的我自己的文件?!??

0

使用SQL Server處理VS 2010和實體框架我已經遇到過這幾次了。在我的情況下,它發生在我嘗試運行該程序時,並且在服務器瀏覽器中打開了一個查詢。一旦失敗,我不得不放棄所有的連接,讓它再次運作。

VS2010將在服務器資源管理器中使用的源數據庫(.MDF.LDF文件)複製到項目調試文件夾。這是您在運行時使用的副本。當複製該文件時,默認情況下,該文件由MDF屬性Copy to Output Directory控制,它被設置爲Copy always。這意味着它會嘗試將文件複製到新的版本或運行中,並且如果您在別處打開該文件,則會失敗,然後會掛起。

查看連接的方式是打開SQL Server管理控制檯。默認情況下,VS2010使用連接字符串中指定的SQL Server用戶實例。對於實體框架,它位於App.Config XML中。

的用戶實例是在具有分配給登錄用戶的所有用戶權限的SQL Server的內存拷貝一個獨立的。爲了達到它,你需要找到正確的連接。

運行從SQL的主要實例此查詢將顯示所有用戶實例連接。

SELECT owning_principal_name, instance_pipe_name, heart_beat FROM sys.dm_os_child_instances 

這將返回的東西,看起來像這樣:

|owning_principle_name | instance_pipe_name      | heart_beat 
-------------------------------------------------------------------------------- 
1 | MyServer\Admin  | \\.\pipe\91B3063E-CD0F-4B\tsql\query\ | dead 
-------------------------------------------------------------------------------- 
2 | MyServer\Rich  | \\.\pipe\B04A1D3B-6268-49\tsql\query\ | alive 

如果複製實例名稱,並在新的連接使用它作爲服務器名稱,運行在用戶與它相關聯,你會從調試文件夾中查看您的數據。

現在,如果你右擊數據庫並選擇Tasks >Detach...您將打開旁邊的數據庫文件名Detach Database對話框檢查Drop Connections複選框,然後單擊OK

數據庫將從列表中刪除,你應該能夠建立並運行你的應用程序。

0

最簡單的事情是去服務器資源管理器。選擇問題數據庫。右鍵單擊並選擇「關閉連接」。

如果它已關閉,則連接並斷開連接。

0

我認爲已經有SqlTestDB.mdf附加。 我以前遇到過這個問題,只需轉到Ms Sql服務器並分離數據庫,然後在Visual Studio的Server Explorer中重建連接。

0

您在開始時打開dbase並且完成後無法確定它正在發佈。真的,你正在等待內存管理器對它進行分類,這取決於系統在何時可以釋放文件。

我認爲你需要將它改爲「需要時打開」。

我例如把代碼訪問任何數據庫在它自己的類,一旦行動已經完成我釋放它。

打開和關閉確實有開銷,但我發現我可以通過執行以下操作忍受它,

有你的班上不止一個入口點,一個單一的交易,另一種爲多次交易。例如

S_UpdateSingleRecord(...) 
M_UpdateManyRecords(...) 

我發現,在大多數應用中,這些可以是靜態的,因爲他們本身不存儲數據,他們只能通過它傳遞和數據庫。如果我想爲我的應用程序緩存某些內容,它只會丟失它的靜態狀態。

我在S_SingleTransaction()中使用'using',因爲它會爲我清理它。但是當我的調用函數完成時,我打開多個入口點並關閉它。我從來沒有遇到過一個單一的mdf和一個應用程序的鎖定問題。它會重新開始使用一個mdf和多個應用程序,在這些情況下,您需要將MSSQL用作服務dbase,而不是在Visual Studio中設置,然後在其他應用程序中您的工具欄上的列表中已經有該數據庫。

相關問題