2012-02-08 101 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中设置,然后在其他应用程序中您的工具栏上的列表中已经有该数据库。

相关问题