2011-01-06 46 views
6

Nếu tôi có một thủ tục được lưu trữ thực hiện một thủ tục đã lưu khác nhiều lần với các đối số khác nhau, có thể có mỗi cuộc gọi này cam kết độc lập với các cuộc gọi khác không?Làm cách nào để đảm bảo rằng các giao dịch lồng nhau được cam kết độc lập với nhau?

Nói cách khác, nếu hai lần thực thi đầu tiên của thủ tục lồng nhau thành công, nhưng lệnh thứ ba thất bại, có thể bảo toàn kết quả của hai lần thực hiện đầu tiên (và không cuộn chúng trở lại) không?

Tôi đã một thủ tục được xác định một cái gì đó được lưu trữ như thế này trong SQL Server 2000:

CREATE PROCEDURE toplevel_proc .. 
AS 
BEGIN 

     ... 

     while @row_count <= @max_rows 
    begin 
     select @parameter ... where rownum = @row_count 
     exec nested_proc @parameter 
     select @row_count = @row_count + 1 
    end 

END 

Trả lời

6

Trước hết, there is no such thing as a nested transaction in SQL Server

Tuy nhiên, bạn có thể sử dụng SAVEPOINTs theo ví dụ này (quá dài để tái tạo ở đây xin lỗi) từ người dùng SO đồng nghiệp Remus Rusanu

Chỉnh sửa: AlexKuznetsov đã đề cập (ông đã xóa câu trả lời của mình) rằng điều này sẽ không hoạt động nếu giao dịch bị xử lý. Điều này có thể xảy ra với SET XACT_ABORT ON hoặc một số lỗi kích hoạt.

3

Từ BOL:

ROLLBACK GIAO DỊCH mà không có một savepoint_name hoặc transaction_name cuộn trở lại đầu giao dịch . Khi lồng ghép các giao dịch , cùng một tuyên bố này sẽ cuộn lại tất cả các giao dịch bên trong thành lệnh BEGIN TRANSACTION ngoài cùng bên ngoài.

Tôi cũng thấy những điều sau đây từ một thread here:

Hãy nhận biết rằng SQL Server giao dịch không thực sự lồng nhau theo cách bạn nghĩ. Khi một giao dịch khai báo được bắt đầu, thì BEGIN số gia tăng TRẦN sau @@ TRANCOUNT trong khi COMMIT giảm giá trị. Toàn bộ giao dịch ngoài cùng là được cam kết khi kết quả COMMIT trong một số không @@ TRANCOUNT. Nhưng một ROLLBACK mà không có điểm lưu trữ cuộn lại tất cả hoạt động bao gồm giao dịch ngoài cùng .

Nếu bạn cần lồng nhau hành vi giao dịch , bạn sẽ cần phải sử dụng TIẾT KIỆM GIAO DỊCH thay vì BEGIN TRAN và sử dụng ROLLBACK TRAN [savepoint_name] thay vì ROLLBACK TRAN.

Vì vậy, nó sẽ xuất hiện có thể.

+1

"sử dụng ROLLBACK TRAN thay vì ROLLBACK TRAN" ?? – Greg

+0

@Greg - cảm ơn vì đã chỉ ra điều đó. Văn bản tôi đã trích dẫn các dấu ngoặc nhọn được sử dụng xung quanh văn bản 'savepoint_name' và điều đó khiến công cụ đánh dấu SO ẩn văn bản. Đã chỉnh sửa văn bản để sử dụng dấu ngoặc vuông. – Tony

+0

Cảm ơn bạn đã sửa nó! – Greg

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