Dưới đây là một cách tiếp cận khác, mà tôi nghĩ là phù hợp cho trường hợp cụ thể khi một thủ tục được gọi trực tiếp bởi người dùng thay vì từ một ứng dụng.
Tôi phải nói, nó đề xuất ít rắc rối hơn cho người dùng trong khi nhiều hơn (có thể, không cân xứng) cho nhà phát triển so với hầu hết các đề xuất khác. Bạn quyết định liệu nó có phù hợp với bạn hay không.
Dù sao, ở đây đi.
Trước tiên, bạn tạo một bảng đặc biệt, CriticalCalls
, để đăng ký cuộc gọi đến các thủ tục quan trọng. Bảng sẽ có một cấu trúc như thế này:
SPID int,
ProcName sysname,
CallTime datetime
Về cơ bản, ý tưởng là một SP quan trọng nên được gọi là hai lần: lần đầu tiên nó đăng ký cuộc gọi và thông báo cho người sử dụng để lặp lại các cuộc gọi trong một khoảng thời gian nhất định như xác nhận ý định của họ và với cuộc gọi thứ hai, nếu được thực hiện tương ứng, nó thực sự tiến hành hoàn thành nhiệm vụ của mình.
Vì vậy, các phần khởi động của tất cả các thủ tục quan trọng sẽ có logic này:
IF NOT EXISTS (
SELECT *
FROM CriticalCalls
WHERE SPID = @@SPID AND ProcName = @ThisProcName
AND GETDATE() - CallTime BETWEEN @LowerCallTimeLimit AND @UpperCallTimeLimit
/* the actual test for the time interval might be somewhat different */
) BEGIN
... /* upsert CriticalCalls with the current time stamp */
PRINT 'To proceed, please call this procedure again within...';
RETURN;
END;
DELETE FROM CriticalCalls WHERE SPID = @@SPID AND ProcName = @ThisProcName;
... /* proceed with your critical task */
Thực ra, tôi nghĩ rằng, nó sẽ là tốt nhất để sử dụng một SP chuyên dụng (tên CheckCriticalCalls
dưới đây) cho tất cả các thao tác với CriticalCalls
, bao gồm tất cả các sửa đổi cần thiết. CheckCriticalCalls
sẽ nhận được tên của thủ tục được kiểm tra và trả về một loại cờ cho biết liệu quy trình được chỉ định có nên thực hiện hoạt động thực của nó hay không.
Vì vậy, nó có thể trông khá như thế này:
EXECUTE @result = CheckCriticalCalls 'ThisProcedureName';
IF @result = -1 BEGIN
PRINT 'Call me again';
RETURN;
END;
... /* go on with the task */
Ý tưởng đằng sau thiết lập các giới hạn dưới của khoảng chỉ đơn thuần là để ngăn chặn người dùng từ gọi một thủ tục quan trọng gấp đôi tự động, tức là bằng cách thực hiện hai giống hệt EXECUTE...
dòng trong một đợt. Giới hạn trên, tất nhiên, là cần thiết để 1) đảm bảo rằng người dùng xác nhận ý định gần đây của họ để thực hiện các hoạt động quan trọng; 2) ngăn chặn thực hiện nếu bản ghi hiện tại trong CriticalCalls
thực sự được để lại ở đó từ một phiên trước đó có cùng SPID.
Vì vậy, về cơ bản, khoảng thời gian từ 1-2 giây đến nửa phút có vẻ khá tự nhiên đối với tôi. Thay vào đó, bạn có thể chọn các hình khác nhau.
Tại sao bạn không thiết lập quyền cho procs được lưu trữ của mình? Bằng cách đó, chỉ những người dùng được ủy quyền mới có thể chạy nó. –
@ The Gentleman Elite: Tôi không nói rằng người dùng có thẩm quyền đôi khi có thể muốn cảm thấy như con người chứ không phải là máy móc. Trường hợp cụ thể này cho thấy rằng một số nhà phát triển không nhớ người dùng chỉ là những người chết. :) –