2012-07-10 36 views
6
USE AdventureWorks; 
GO 
BEGIN TRANSACTION; 
GO 
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 10; 
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 11; 
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 12; 
GO 
COMMIT TRANSACTION; 
GO 

Điều gì sẽ xảy ra nếu câu lệnh xóa đầu tiên không thành công? Câu lệnh xóa thứ 2 và thứ 3 có được thực hiện không? Ví dụ này không có bất kỳ xử lý lỗi nào, nó sẽ để lại một giao dịch mở trong trường hợp ngoại lệ hay SQL Server sẽ tự động quay lại giao dịch? Mở giao dịch = tài nguyên bị khóa, phải không?Có phải giao dịch ROLLBACK không?

Tôi đang quyết định có nên áp dụng TRY ... CATCH cho các thủ tục được lưu trữ sử dụng giao dịch hay không.

Tôi biết về set xact_abort on, nhưng muốn biết điều gì xảy ra mà không có nó.

Đây là những gì tôi tìm thấy trong tài liệu - Kiểm soát giao dịch (Database Engine):

Nếu một lỗi ngăn cản việc hoàn thành một giao dịch, SQL Server tự động cuộn lại giao dịch và giải phóng mọi nguồn lực tổ chức bởi giao dịch

Tuy nhiên, tôi đọc trong các bài đăng khác rằng khôi phục tự động không được kích hoạt.

+0

Có, sử dụng try ... catch. – Ben

Trả lời

11

Trong ví dụ của bạn, mà không cần dùng SET XACT_ABORT ON, giao dịch sẽ tiếp tục và cam kết ngay cả khi báo cáo kết quả đầu tiên thất bại. Trong văn bản bạn trích dẫn, các từ khóa là if an error **prevents** the successful completion of a transaction và lỗi DELETE không ngăn giao dịch hoàn tất.

Ví dụ về lỗi gây ra khôi phục tự động là nếu kết nối với cơ sở dữ liệu bị cắt ở giữa giao dịch. Tiếp tục xuống MSDN article bạn tham chiếu nói:

Nếu một lỗi tuyên bố thời gian chạy (ví dụ như vi phạm chế) xảy ra trong đợt một, hành vi mặc định trong cơ sở dữ liệu là để cuộn lại chỉ tuyên bố rằng đã tạo lỗi. Bạn có thể thay đổi hành vi này bằng cách sử dụng câu lệnh SET XACT_ABORT. Sau khi SET XACT_ABORT ON được thực thi, bất kỳ lỗi báo cáo thời gian chạy nào cũng gây ra một cuộn lùi tự động của giao dịch hiện tại. Lỗi biên dịch, chẳng hạn như lỗi cú pháp, là không bị ảnh hưởng bởi SET XACT_ABORT.

Bạn nên sử dụng xử lý lỗi để phát hiện lỗi và khôi phục nếu cần.

+0

Vì vậy, nó sẽ rollback tuyên bố xóa đầu tiên không thành công, sau đó bắt đầu thực hiện một thứ hai, và sau đó trong cùng một cách - thứ 3? Và cuối cùng sẽ đi xuống để cam kết tuyên bố? Điều đó có nghĩa là lỗi trong một câu lệnh sẽ không dừng việc thực thi hàng loạt, đúng không? –

+0

Đúng vậy. Ngoài ra, tôi đã cập nhật câu trả lời của mình (hy vọng) rõ ràng hơn một chút :) –

5

tôi thích để kiểm soát quá trình này bằng tay:

BEGIN TRY 
BEGIN TRAN 

    -- do work 

COMMIT 
END TRY 
BEGIN CATCH 
    ROLLBACK 
    RAISERROR (...) 
END CATCH 
GO 
Các vấn đề liên quan