Sau khi câu lệnh UPDATE đã được thực hiện, hiệu ứng của câu lệnh sẽ hiển thị cho phần còn lại của giao dịch (và nếu bạn cam kết, với các giao dịch khác). Theo thứ tự Oracle sẽ làm gì, là chi tiết thực hiện (tương tự như cách mà thứ tự kết quả SELECT không được bảo đảm trừ khi bạn chỉ định ORDER BY).
Trong hầu hết các trường hợp, thứ tự này không quan trọng với khách hàng. Một trường hợp mà nó có thể là để tránh deadlocks với một giao dịch đang cập nhật tập hợp các hàng chồng chéo. UPDATE sẽ khóa hàng đang được cập nhật cho đến khi kết thúc giao dịch, vì vậy nếu hai giao dịch cố gắng khóa các hàng tương tự, nhưng theo thứ tự khác nhau, một bế tắc có thể xảy ra.
Cách tiêu chuẩn để tránh deadlocks là luôn luôn khóa theo thứ tự được xác định rõ ràng. Rất tiếc, UPDATE không có mệnh đề ORDER BY, nhưng bạn có thể thực hiện điều này:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT ... WHERE condition ORDER BY ... FOR UPDATE;
UPDATE ... WHERE condition;
COMMIT;
Trường hợp condition
tương tự cho cả hai câu lệnh. Mức cô lập tuần tự là cần thiết cho WHERE
để luôn thấy cùng một tập hợp các hàng trong cả hai câu lệnh.
Hoặc, trong PL/SQL bạn có thể làm một cái gì đó như thế này:
DECLARE
CURSOR CUR IS SELECT * FROM YOUR_TABLE WHERE condition ORDER BY ... FOR UPDATE;
BEGIN
FOR LOCKED_ROW IN CUR LOOP
UPDATE YOUR_TABLE SET ... WHERE CURRENT OF CUR;
END LOOP;
END;
/
Nguồn
2012-03-04 17:06:03
Một cách logic, chúng xảy ra đồng thời. Trong thực tế, họ không, nhưng bạn sẽ không thể phát hiện sự khác biệt. Sẽ thú vị hơn nếu bạn làm 'UPDATE Table1 SET Index = Index + 1 WHERE Index GIỮA 1 VÀ 5'. –