2012-07-13 27 views
5

Có một rollback bên trong một INSERT SAU hoặc một UPDATE SAU KHI kích hoạt rollback toàn bộ giao dịch hoặc chỉ hàng hiện tại đó là lý do kích hoạt, và là nó giống nhau với Cam kết?Có một rollback bên trong một INSERT SAU hoặc UPDATE SAU KHI kích hoạt rollback toàn bộ giao dịch

Tôi đã cố gắng kiểm tra mã thông qua các mã dự án hiện tại sử dụng MSTDC cho các giao dịch và có vẻ như giao dịch hoàn tất bị hủy bỏ.

Nếu một Rollback trong trình kích hoạt quay lại toàn bộ giao dịch, có cách giải quyết để hạn chế nó chỉ các hàng hiện tại không.

Tôi tìm thấy một liên kết cho sybase về vấn đề này, nhưng không có gì trên máy chủ sql

+1

Doe SQL Server thực sự cho phép 'rollback' trong trình kích hoạt? –

+0

Tôi đoán nó, b'coz tôi đã viết một, và nó đã không ném bất kỳ lỗi khi thực hiện các kịch bản và kích hoạt đang làm việc quá. – Vamsi

+1

Chà. Đó là đáng sợ –

Trả lời

7

Có nó sẽ rollback toàn bộ giao dịch.

Đó là tất cả trong số docs (xem Ghi chú). Lưu ý nhận xét tôi đã nhấn mạnh - điều đó khá quan trọng tôi sẽ nói !!

Nếu GIAO DỊCH ROLLBACK được ban hành trong một trigger:

Tất cả các thay đổi dữ liệu được thực hiện đến thời điểm đó trong giao dịch hiện tại được cuộn lại, bao gồm bất kỳ do cò.

Trình kích hoạt tiếp tục thực hiện bất kỳ câu lệnh còn lại sau câu lệnh ROLLBACK. Nếu bất kỳ câu nào trong số các câu lệnh này sửa đổi dữ liệu, các sửa đổi sẽ không được khôi phục. Không có trình kích hoạt lồng nhau nào được kích hoạt bởi việc thực hiện các câu lệnh còn lại này.

Các câu lệnh trong lô sau khi phát biểu kích hoạt trình kích hoạt không được thực thi.

+1

Vì vậy, có cách giải quyết nào không? – Vamsi

+4

Tại sao bạn cần giải pháp? Trình kích hoạt chỉ là mã giống như bất kỳ mã nào khác - bạn kiểm soát chính xác vị trí bạn muốn quay lại mọi lúc. – Jimbo

+0

Tôi nghĩ rằng những gì anh ta yêu cầu là quay ngược lại những hàng có liên quan với câu lệnh chèn/cập nhật đã kích hoạt trình kích hoạt. Để làm điều đó, tôi đoán một người sẽ cần phải đặt một điểm lưu trữ trong người gọi, gọi chèn/cập nhật, từ phía trình kích hoạt gây ra lỗi dựa trên logic nào đó nếu cần, sau đó trong trình gọi, hãy bắt lỗi và quay lại điểm lưu trữ . Tôi đã không thử nó mặc dù. Một thiết kế tốt hơn (ngoại lệ miễn phí) có thể là để kiểm tra điều kiện trong người gọi và thậm chí không cố gắng chèn/cập nhật các hàng đó ngay từ đầu. – crokusek

0

Bất kỳ lệnh rollback nào sẽ quay trở lại mọi thứ cho đến @@ trancount là 0 trừ khi bạn chỉ định một số điểm lưu trữ và không quan trọng bạn đặt lệnh rollback tran ở đâu.

Cách tốt nhất là xem lại mã một lần nữa và xác nhận yêu cầu kinh doanh và xem tại sao bạn cần khôi phục kích hoạt?

1

Như bạn đã được biết, lệnh ROLLBACK không thể sửa đổi/điều chỉnh sao cho nó chỉ quay lại các câu lệnh do trigger kích hoạt.

Nếu bạn chỉ cần kích hoạt hành động "rollback", bạn có thể, là giải pháp thay thế, hãy xem xét sửa đổi trình kích hoạt theo cách mà trước khi thực hiện hành động, trình kích hoạt đảm bảo các hành động đó không tạo ra các tình huống đặc biệt có thể khiến toàn bộ giao dịch quay trở lại. Ví dụ:

Ví dụ: nếu trình kích hoạt của bạn chèn hàng, hãy thêm dấu kiểm để đảm bảo các hàng mới không vi phạm ví dụ:ràng buộc duy nhất (hoặc ràng buộc khoá ngoại), một cái gì đó như thế này:

IF NOT EXISTS (
    SELECT * 
    FROM TableA 
    WHERE … /* a condition to test if a row or rows you are about 
       to insert aren't going to violate any constraint */ 
) 
BEGIN 
    INSERT INTO TableA … 
END; 

Hoặc, nếu kích hoạt của bạn xóa hàng, kiểm tra nếu nó không cố gắng để xóa hàng tham chiếu bởi các bảng khác (trong trường hợp bạn thường cần phải biết trước đó bảng sức tham khảo các hàng):

IF NOT EXISTS (
    SELECT * FROM TableB WHERE … 
) 
AND NOT EXISTS (
    SELECT * FROM TableC WHERE … 
) 
AND … 
BEGIN 
    DELETE FROM TableA WHERE … 
END 

Tương tự như vậy, bạn sẽ cần phải thực hiện kiểm tra các báo cáo cập nhật, nếu có.

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