2012-02-08 27 views
5

Tôi đã viết một chương trình C# rất nhỏ, sử dụng cơ sở dữ liệu SQL Server rất nhỏ, hoàn toàn cho một số mục đích thử nghiệm &. Cơ sở dữ liệu được sử dụng trong một dự án mới này và không có nơi nào khác. Tuy nhiên, tôi đang gặp sự cố khi chạy Gỡ lỗi trong đó chương trình sẽ không chạy, vì cơ sở dữ liệu "đang được sử dụng bởi một quá trình khác".Cơ sở dữ liệu đang được sử dụng bởi một quy trình khác ... nhưng quy trình nào?

Nếu tôi khởi động lại máy, nó sẽ hoạt động trở lại và sau một vài lần chạy thử, tôi sẽ gặp lại vấn đề tương tự.

Tôi đã tìm thấy nhiều, nhiều sự cố tương tự được báo cáo trên Internet, nhưng không tìm thấy câu trả lời dứt khoát nào về cách giải quyết vấn đề này. Thứ nhất, làm cách nào để tìm hiểu "quy trình khác" đang sử dụng tệp .mdf & .ldf của tôi? Sau đó, làm thế nào để tôi có được những tập tin này phát hành & không được tổ chức để ngăn chặn điều này xảy ra thời gian sau khi thời gian sau khi thời gian?!?

Tôi mới dùng VS2010, SQL Server & C#, vì vậy hãy mô tả khá rõ trong bất kỳ câu trả lời nào bạn cho tôi !!!

Đây là mã của tôi, như bạn có thể thấy, bạn không thể có được bất cứ điều gì cơ bản hơn nhiều, tôi chắc chắn không nên chạy vào rất nhiều vấn đề !!!

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

Bạn có nhận được thông báo lỗi tương tự khi bạn chạy ứng dụng của mình lần đầu không? Nếu bạn nhận được lỗi này lần thứ hai trở đi, tôi đoán ứng dụng của bạn không đóng kết nối db đúng cách. –

+1

Khi tôi lần đầu tiên chạy chương trình, nó hoạt động tốt và tiếp tục hoạt động, nhưng tôi đang gỡ lỗi và dừng chương trình mà không hoàn thành một cách hợp lý đôi khi. Có vẻ như không phải là một điểm thường xuyên mà tại đó điều này bắt đầu xảy ra mặc dù, nhưng có lẽ nó được kết nối với tôi ngừng gỡ lỗi mà không đóng DB. VS2010 sẽ không xử lý điều đó mặc dù?!? –

Trả lời

6

Các tùy chọn khả năng nhất:

  1. Một trước (bị rơi) thể hiện của chương trình của bạn
  2. Visual Studio (với một nhà thiết kế Bảng mở hoặc một cái gì đó tương tự)

Bạn có thể kiểm tra 1) với TaskManager và 2) bằng cách tìm trong Server Explorer. Db của bạn nên hiển thị một chữ thập đỏ nhỏ có nghĩa là 'đóng'.

Và bạn nên viết lại mã của mình để đóng kết nối càng sớm càng tốt. Sử dụng các khối try/finally hoặc using(){ }.

+0

Vâng, liên quan đến việc viết lại mã của tôi, đó là lý do cho chương trình nhỏ này, để tôi có thể xác định cách tốt nhất để tôi viết mã xử lý SQL-Server để sử dụng trong chương trình thực sự của mình !! Trong Seerver Explorer, DB của tôi có chữ thập đỏ, nhưng tôi vẫn nhận được thông báo lỗi. –

0

thử chạy sp_who2 để xem danh sách quy trình.

FYI: bạn không cần phải khởi động lại máy tính của bạn, trường hợp xấu nhất, khởi động lại SQL Server dịch vụ

+0

Tôi sẽ cố gắng này trong một thời gian ngắn, phải thu thập các trẻ em từ trường ngay bây giờ ... nếu bạn là chính xác mà sẽ giúp tôi tiết kiệm rất nhiều thời gian !!! –

+0

ok, hãy cho chúng tôi biết :) – Diego

+0

OK, VS2010 sẽ không cho phép tôi mở truy vấn mới, nó cho biết "Không thể mở tệp vật lý ..... Lỗi hệ điều hành 32:" 32 (không truy xuất được văn bản này Lý do: 15105). Một nỗ lực để đính kèm một cơ sở dữ liệu tự động đặt tên cho tập tin ..... thất bại.Một cơ sở dữ liệu có cùng tên tồn tại, hoặc tập tin được chỉ định không thể mở được, hoặc nó nằm trên chia sẻ UNC. ", Vì vậy, tôi chạy sp_who2 trong SQL Server Management Studio và có 31 kết quả, chỉ có 2 phần dưới có vẻ liên quan đến cơ sở dữ liệu này Có nghĩa là họ có MySqlDB trong cột DBName –

0

IIRC sử dụng AttachDbFilename quay lên một quá trình SqlServr.exe chạy theo người sử dụng chiếm quá trình của bạn là sử dụng, tách biệt với các trường hợp SQLServer chạy như một dịch vụ (vì vậy dừng dịch vụ MsSqlServer không dừng vấn đề này). Trong trường hợp của một lối ra bẩn, đôi khi quá trình này không được làm sạch. Tôi nghi ngờ rằng việc giết chết quá trình này sẽ giải phóng các tệp db.

+0

Theo trả lời của tôi dưới đây, quá trình giết chết có, cho đến nay, không giúp đỡ ... –

+0

Tôi đã phải đi vào Dịch vụ & tìm MSSQLSERVER, thay đổi tùy chọn Bắt đầu Hướng dẫn sử dụng, sau đó thể chất Ngừng nó ... hơn và chỉ sau đó, là tôi có thể xóa các tập tin trong thư mục bin \ debug !!! Tôi đã thay đổi tùy chọn Bắt đầu quay lại Tự động và bắt đầu Dịch vụ và cuối cùng, tất cả hoạt động trở lại! Bây giờ tôi phải tìm hiểu lý do tại sao nó xảy ra và ngăn chặn nó xảy ra một lần nữa ... –

0

Hãy thử sử dụng Process Explorer được viết bởi Mark Russinovich, một thành viên kỹ thuật của Microsoft. Đó là một công cụ quân đội swiss tiêu chuẩn trong túi của Windows Admins/Developers. Nó có thể cho bạn thấy những gì các quy trình đang nắm giữ các xử lý trên các tài nguyên trong hệ thống.

Một khi bạn đã Process Explorer được cài đặt, hãy thử như sau:

  1. Nhận hệ thống của bạn thành một thất bại nhà nước (ví dụ rằng chạy chương trình của bạn không hoạt động).
  2. Khởi động Process Explorer (bạn cần phải là Quản trị viên để tận dụng các tính năng của nó).
  3. Nhấp vào "Tìm" trong thanh trình đơn ở trên cùng và nhập tên tệp .mdf hoặc .ldf của bạn.

Kết quả tìm kiếm sẽ hiển thị một quy trình/dịch vụ có tay cầm trên một trong các tài nguyên vẫn bị tổ chức bởi quá trình chấm dứt sai.

+0

Nó tìm thấy tập tin LDF, nhưng theo trả lời của tôi để Diego (ở trên) giết chết quá trình không phát hành nó :-(!!! –

+0

Tôi đã phải vào Dịch vụ & tìm MSSQLSERVER, thay đổi tùy chọn Bắt đầu thành Thủ công, rồi dừng lại ... và chỉ sau đó, tôi có thể xóa các tệp trong thư mục bin \ debug !!! tùy chọn quay lại Tự động và bắt đầu Dịch vụ và cuối cùng, tất cả đều hoạt động trở lại! Bây giờ tôi phải tìm hiểu lý do tại sao nó đang xảy ra và ngăn nó xảy ra lần nữa ... –

1

Đây là mã được viết lại, sử dụng câu lệnh "Sử dụng". Khi tôi thực hiện chương trình và nhấn vào Insert Record Into SQL File, tắt nó đi, hoàn thành quá trình với myCount = 1 (mặc dù tôi không chắc chắn 100% rằng nó thực sự đang thực hiện một Write vật lý), tôi thiếu một lệnh thực sự "cam kết" cập nhật?!?) và hiển thị lại Biểu mẫu.

Nếu tôi sau đó bấm vào Insert Record Into SQL tập tin một lần nữa, tôi nhận được một lỗi như sau:

SqlException was unhandled

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

Đây là chương trình (Tôi là người duy nhất trên máy tính này và có quyền quản trị đầy đủ, "Nhà nước" của cơ sở dữ liệu tại thời điểm này là, theo Properties, Closed, do đó, nó trông giống như lần đầu tiên thông qua mã đã làm như mong đợi ...

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; 
    } 

} 
} 

Tôi không hiểu tại sao tôi đột nhiên mất quyền truy cập vào tệp của riêng tôi mà tôi đã sử dụng?!?

0

Làm việc với VS 2010 và khung thực thể bằng cách sử dụng SQL Server Tôi đã chạy vào điều này nhiều hơn một vài lần. Trong trường hợp của tôi nó xảy ra khi tôi cố gắng chạy chương trình và tôi đã có một truy vấn mở trong Server Explorer. Một khi nó không thành công tôi đã phải thả tất cả các kết nối để làm cho nó hoạt động trở lại.

VS2010 sao chép cơ sở dữ liệu nguồn (tệp .MDF.LDF) mà bạn làm việc với trong Trình khám phá máy chủ vào thư mục gỡ lỗi dự án. Đây là bản sao bạn đang làm việc với thời gian chạy. Khi tệp này được sao chép được kiểm soát bởi thuộc tính MDF Copy to Output Directory theo mặc định, nó được đặt thành Copy always. Điều này có nghĩa là nó sẽ cố gắng và sao chép các tập tin trên một xây dựng mới hoặc chạy và nếu bạn có nó mở ở nơi khác nó không thành công và sau đó nó được treo lên.

Cách để xem kết nối là mở Bảng điều khiển quản lý SQL Server. Theo mặc định, VS2010 đang sử dụng một cá thể người dùng của SQL Server như được chỉ định trong chuỗi kết nối. Trong trường hợp của Entity Frameworks, nó nằm trong XML App.Config.

Ví dụ người dùng là một bản sao bộ nhớ riêng biệt của SQL Server có tất cả quyền người dùng được gán cho người dùng đã đăng nhập. Để có được nó, bạn cần phải tìm kết nối thích hợp.

Chạy truy vấn này từ phiên bản chính của SQL sẽ hiển thị tất cả các kết nối Trường hợp người dùng.

SELECT owning_principal_name, instance_pipe_name, heart_beat FROM sys.dm_os_child_instances 

này sẽ trở lại cái gì đó trông như thế này:

|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 

Nếu bạn sao chép tên ví dụ và sử dụng nó như tên máy chủ trong một kết nối mới, chạy như người sử dụng gắn liền với nó, bạn sẽ xem dữ liệu của bạn từ thư mục gỡ lỗi.

Bây giờ nếu bạn nhấp chuột phải vào cơ sở dữ liệu và chọn Tasks >Detach... Bạn sẽ mở ra một Detach Database séc thoại vào hộp kiểm Drop Connections bên cạnh tên tập tin cơ sở dữ liệu và nhấp OK.

Cơ sở dữ liệu sẽ bị xóa khỏi danh sách và bạn sẽ có thể tạo và chạy ứng dụng của mình.

0

tôi tìm thấy giải pháp này tại địa chỉ: http://oreilly.com/catalog/errata.csp?isbn=0636920022220

Kích chuột phải vào cơ sở dữ liệu trong cơ sở dữ liệu nhà thám hiểm VS và nhấp vào kết nối chặt chẽ giữa các phiên gỡ lỗi và nó làm việc cho tôi.

0

Điều đơn giản nhất là vào Server Explorer. Chọn cơ sở dữ liệu vấn đề. Nhấp chuột phải và chọn "Đóng kết nối".

Nếu đã đóng, hãy kết nối và ngắt kết nối.

0

Tôi nghĩ rằng đã có SqlTestDB.mdf được đính kèm. Tôi đã phải đối mặt với vấn đề này trước, chỉ cần đi đến máy chủ Ms Sql và tách cơ sở dữ liệu sau đó xây dựng lại kết nối của bạn tại Server Explorer trong Visual Studio.

0

Bạn đang mở dbase lúc bắt đầu và không chắc chắn rằng nó đang được phát hành khi kết thúc. Thực sự bạn đang chờ người quản lý bộ nhớ sắp xếp nó ra, nó phụ thuộc vào cách hệ thống bận rộn như thế nào khi tệp có thể được phát hành.

Tôi nghĩ rằng bạn cần thay đổi điều này thành "Mở khi cần".

Ví dụ: tôi đặt mã để truy cập vào bất kỳ cơ sở dữ liệu nào trong lớp riêng của nó, khi các hành động đã được hoàn thành, tôi phát hành nó.

mạc và bế mạc không có chi phí, nhưng tôi đã tìm thấy tôi có thể sống với nó bằng cách làm những điều sau đây,

Có nhiều hơn một điểm vào trong lớp học của bạn, một cho các giao dịch duy nhất, và một cho nhiều giao dịch. Ví dụ:

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

Tôi thấy rằng trong hầu hết các ứng dụng này có thể tĩnh, vì bản thân chúng không lưu trữ dữ liệu mà chúng chỉ truyền dữ liệu đến và từ cơ sở dữ liệu. Nó chỉ mất trạng thái tĩnh của nó nếu tôi muốn cache một cái gì đó cho ứng dụng của tôi.

Tôi sử dụng 'using' trong S_SingleTransaction() vì nó làm sạch nó cho tôi. Nhưng tôi để lại nhiều entrypoint mở và đóng nó khi chức năng gọi của tôi kết thúc. Tôi chưa bao giờ gặp vấn đề về khóa này với một mdf và một ứng dụng. Nó sẽ trở lại chơi với một mdf và nhiều ứng dụng, trong những trường hợp này bạn cần sử dụng MSSQL làm dbase dịch vụ thay vào đó, bạn sẽ thấy nó dễ dàng cài đặt trong Visual Studio, và sau đó trong các ứng dụng khác đã có cơ sở dữ liệu đó trong danh sách trong thanh công cụ của bạn.

Các vấn đề liên quan