2014-09-13 16 views
5

Tôi có một thủ tục được lưu trữ đang cập nhật nhiều bảng trong SQL Server. Thủ tục này đang được sử dụng từ mã C#.Chúng ta có cần áp dụng Giao dịch Sql ở cả mã C# và Thủ tục lưu sẵn không?

Nếu tôi áp dụng giao dịch chỉ trong mã C#, đó có phải là phương pháp hay không?

Tôi có cần áp dụng giao dịch trong cả mã C# và quy trình được lưu trữ không?

Cảm ơn

Trả lời

6

Nếu quá trình này chỉ được gọi một thủ tục lưu trữ duy nhất trong một đơn SqlCommand, sau đó chỉ cần xử lý các giao dịch bên trong thủ tục lưu trữ và không có nhu cầu để quản lý nó từ mã C#. Bạn chỉ cần quản lý nó trong mã C# để duy trì giao dịch qua nhiều lần thực hiện SqlCommand.

FYI, quản lý giao dịch trong cả hai lớp là chỉ cần thiết nếu cả hai sau là đúng:

  • mã C# đang thực hiện nhiều SqlCommand cuộc gọi mà cần phải được coi là một hoạt động đơn lẻ
  • các lưu trữ (các) thủ tục có thể/sẽ được gọi bên ngoài mã C# này, chẳng hạn như bởi các thủ tục được lưu trữ khác (trong trường hợp đó có thể không có Giao dịch hiện tại tại thời điểm thủ tục được lưu trữ) được gọi là

Bên ngoài o f kịch bản trên, quản lý giao dịch trong cả hai lớp là vô nghĩa vì chỉ có một giao dịch duy nhất. Nếu giao dịch được bắt đầu bằng mã C#, thì tất cả điều đó xảy ra trong quy trình được lưu trữ khi số BEGIN TRAN được gọi là số @@TRANCOUNT được tăng lên. Và giao dịch không thực sự được cam kết cho đến khi @@TRANCOUNT quay trở lại 0 bằng cách phát hành cùng một số COMMIT s như được hiển thị trong @@TRANCOUNT (trong trường hợp này, hãy phát hành COMMIT trong thủ tục được lưu trữ và một lần nữa trong mã C#, tại thời điểm đó SQL Máy chủ thực sự thực sự "cam kết" thực sự. Tuy nhiên, một đơn ROLLBACK mang lại @@TRANCOUNT quay lại 0 cho dù số đó là bao nhiêu. Và nếu điều đó xảy ra trong Proc được lưu trữ, bạn không thể phát hành COMMIT hoặc ROLLBACK trong mã C# vì giao dịch không còn tồn tại, vì vậy trước tiên bạn cần kiểm tra giao dịch hoạt động.

Giả sử rằng bạn đang sử dụng ít nhất là SQL Server 2005, nếu không phải mới hơn, hãy chắc chắn để sử dụng cú pháp của T-SQL TRY/CATCH để quản lý các COMMIT/ROLLBACK trong thủ tục lưu trữ. Bạn sẽ cần cú pháp TRY/CATCH để nắm bắt đúng các lỗi và thoát khỏi (các) proc ngay cả khi bạn chỉ quản lý giao dịch trong mã C#.

Ví dụ:

BEGIN TRY 

    BEGIN TRAN; 

    UPDATE Table1 ... ; 

    UPDATE Table2 ... ; 

    UPDATE Table3 ... ; 

    COMMIT TRAN; 

END TRY 
BEGIN CATCH 

    IF (@@TRANCOUNT > 0) 
    BEGIN 
    ROLLBACK TRAN; 
    END; 

    THROW; -- if using SQL Server 2012 or newer, else use RAISERROR 

END CATCH; 
+0

Oh thần, giao dịch SQL Server lồng nhau .. tránh như tránh tà. Ít nhất gây nên không có liên quan. Đây là một trong số ít các lĩnh vực mà tôi sẽ đá một nhà phát triển SQL Server, cho một cơ hội. – user2864740

+0

Cảm ơn rất nhiều ... Tôi đang thực hiện nhiều SqlCommand và mỗi lệnh đang cập nhật nhiều bảng bằng cách sử dụng proc trong Sql Server 2008 R2, Vì vậy, trong trường hợp đó nếu tôi sử dụng giao dịch chỉ ở mức mã C#, điều đó sẽ hoạt động tốt? –

+0

@AbhishekSrivastava: kiểm tra câu trả lời đã cập nhật của tôi khi tôi giải quyết tình huống đó trong khi bạn phải thêm nhận xét ;-). Tất cả đều đi xuống cho dù các thủ tục lưu trữ có thể được gọi bằng các thủ tục lưu trữ khác, hoặc cá nhân bằng mã C# khác có thể không được gói trong một giao dịch. –

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