2010-05-18 36 views
7

Tôi có câu hỏi tương tự với how to check if you are in a transaction. Thay vì kiểm tra, làm cách nào để cho phép các giao dịch lồng nhau?Làm cách nào để bật các giao dịch lồng nhau với ADO.NET và SQL Server?

Tôi đang sử dụng Cơ sở dữ liệu Microsoft SQL Server với ADO.NET. Tôi đã thấy các ví dụ sử dụng T-SQL và các ví dụ bắt đầu các giao dịch bằng cách bắt đầu và sử dụng các tên giao dịch. Khi gọi connection.BeginTransaction, tôi gọi một chức năng trong cùng một kết nối, và nó gọi BeginTransaction một lần nữa mang đến cho tôi những ngoại lệ:

SqlConnection does not support parallel transactions. 

Nó xuất hiện nhiều phiên bản của Microsoft cho phép điều này, nhưng tôi không thể tìm ra cách để làm điều đó với tệp .mdf của tôi.

Làm cách nào để cho phép các giao dịch lồng nhau với Cơ sở dữ liệu Microsoft SQL Server bằng C# và ADO.NET?

Trả lời

7

SQL Server nói chung không hỗ trợ giao dịch lồng nhau. Trong T-SQL, bạn có thể phát hành BEGIN TRAN bên trong BEGIN TRAN trước đó nhưng đây chỉ là để thuận tiện. Nó chỉ là giao dịch bên ngoài đếm. Máy khách .NET cho SQL Server (SqlConnection) thậm chí không cho phép bạn thực hiện điều đó và ném ngoại lệ này khi bạn thử.

+0

Máy chủ của tôi cho biết họ cung cấp 'Microsoft SQL 2008'. Đây có phải là T-SQL không? Nếu không có T-SQL ở đâu? Tôi chỉ muốn giao dịch bên ngoài đếm. Liệu 'Microsoft SQL 2008' có cho phép điều này không? (có lẽ để cấu hình nó không để ném một ngoại lệ?) –

+0

T-SQL là biến thể của Microsoft của tiêu chuẩn SQL chạy trong tất cả các phiên bản của SQL Server. Nếu bạn muốn tránh ngoại lệ này, chỉ cần tránh gọi 'BeginTransaction' trước khi cam kết hoặc quay lại giao dịch trước đó - bạn không thể là giao dịch nếu giao dịch trước đó vẫn đang chờ xử lý. Tôi khuyên bạn nên xem xét việc sử dụng TransactionScope (http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope(VS.80).aspx) thay vì cố tự quản lý chúng. –

+0

hmm, đó không phải là điều tương tự. Mã này đã được sử dụng với sqlite và tôi không chắc chắn nếu đó là hỗ trợ với nó (nó có thể được vì nó có vẻ như để hỗ trợ tất cả các ado.net). Nhưng điều này nghe có vẻ kỳ lạ, nếu T-SQL là trong tất cả các phiên bản của máy chủ sql thì tôi không nên có điều đó và không nên cho phép điều này? Đó là một trong những tính năng sẽ làm cho cuộc sống của tôi dễ dàng hơn. Mặc dù theres chỉ có một chức năng sử dụng nó (tôi đoán tôi có thể phá hủy nó kể từ khi nó chỉ trên init, nơi chỉ có một kết nối được sử dụng cho đến khi thực hiện.) –

1
SqlConnection conn = new SqlConnection(@"Data Source=test;Initial Catalog=test;User ID=usr;Password=pass"); 
conn.Open(); 
var com = conn.CreateCommand(); 

com.CommandText = "BEGIN TRANSACTION"; 
com.ExecuteNonQuery(); 
com.CommandText = "BEGIN TRANSACTION"; 
com.ExecuteNonQuery(); 
com.CommandText = "INSERT INTO testTable (ParamName,ParamValue) values ('test','test');"; 
com.ExecuteNonQuery(); 
com.CommandText = "COMMIT TRANSACTION"; 
com.ExecuteNonQuery(); 
com.CommandText = "ROlLBACK TRANSACTION"; 
com.ExecuteNonQuery(); 

com.CommandText = "SELECT COUNT(*) FROM testTable "; 

MessageBox.Show(string.Format("Found {0} rows.", com.ExecuteScalar())); 
+0

Câu trả lời này có thể được hưởng lợi từ một số nhận xét về những gì bạn đã khám phá bằng cách chạy nó. – jocull

3

Quan niệm sai lầm phổ biến là SQL Server hỗ trợ các giao dịch lồng nhau. Nó không. mở nhiều giao dịch và sau đó gọi cam kết hoàn toàn không có gì. bạn có thể dễ dàng viết một số SQL thử nghiệm để tự mình thử. Tùy chọn duy nhất ở đây để mô phỏng giao dịch lồng nhau là sử dụng Savepoints.

Tôi nên thêm rằng điều duy nhất quan trọng là khi @@ TRAN_COUNT đạt đến 0 là điểm mà tại đó chỉ giao dịch bên ngoài sẽ được cam kết.

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