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;
Nguồn
2014-09-13 05:33:03
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
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? –
@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. –