Cursor FOR UPDATE và WHERE CURRENT OF
FOR UPDATE biến cursor thành luồng đọc-để-sửa: Oracle khóa row trong active set và WHERE CURRENT OF cập nhật row mà cursor đang đứng.
FOR UPDATE
Thêm FOR UPDATE OF salary vào query cursor để khóa các dòng sẽ sửa. Lock được giữ tới COMMIT hoặc ROLLBACK.
NOWAIT báo lỗi ngay nếu row đã bị session khác khóa; SKIP LOCKED bỏ qua row đang khóa, hữu ích cho job queue.
WHERE CURRENT OF
Sau FETCH, UPDATE employees SET ... WHERE CURRENT OF c_emp cập nhật chính row hiện tại mà không lặp điều kiện khóa chính.
Cursor phải được khai báo FOR UPDATE và vẫn đang OPEN.
Rủi ro
- Giữ cursor/transaction quá lâu gây blocking.
- COMMIT bên trong loop làm mất locks và có thể khiến fetch tiếp theo lỗi.
- Thứ tự lock khác nhau giữa sessions có thể gây deadlock.
Nếu có thể làm bằng một câu UPDATE set-based thì thường nhanh và đơn giản hơn cursor.
Dùng cursor FOR UPDATE khi logic thật sự phụ thuộc từng row; không dùng chỉ để thay một UPDATE thông thường.
Thuật ngữ (di chuột để xem giải thích)
Đang tải dữ liệu mẫu…
FOR UPDATE
Thêm FOR UPDATE OF salary vào query cursor để khóa các dòng sẽ sửa. Lock được giữ tới COMMIT hoặc ROLLBACK.
NOWAIT báo lỗi ngay nếu row đã bị session khác khóa; SKIP LOCKED bỏ qua row đang khóa, hữu ích cho job queue.
WHERE CURRENT OF
Sau FETCH, UPDATE employees SET ... WHERE CURRENT OF c_emp cập nhật chính row hiện tại mà không lặp điều kiện khóa chính.
Cursor phải được khai báo FOR UPDATE và vẫn đang OPEN.
Rủi ro
- Giữ cursor/transaction quá lâu gây blocking.
- COMMIT bên trong loop làm mất locks và có thể khiến fetch tiếp theo lỗi.
- Thứ tự lock khác nhau giữa sessions có thể gây deadlock.
Nếu có thể làm bằng một câu UPDATE set-based thì thường nhanh và đơn giản hơn cursor.
Dùng cursor FOR UPDATE khi logic thật sự phụ thuộc từng row; không dùng chỉ để thay một UPDATE thông thường.
Thuật ngữ (di chuột để xem giải thích)
Đang tải dữ liệu mẫu…
Oracle PL/SQL. Browser không có Oracle Server; editor dùng dialect PL/SQL và nút bên dưới chạy mô phỏng trên dữ liệu mẫu.
Đang tải trình soạn thảo…
Khai báo cursor c_orders chọn id,total từ orders WHERE total < 50 FOR UPDATE OF total; OPEN và FETCH vào v_id/v_total.
Đang tải trình soạn thảo…
Trong loop của c_orders FOR UPDATE, tăng total 5 bằng UPDATE orders ... WHERE CURRENT OF c_orders. Không COMMIT bên trong loop.
Đang tải trình soạn thảo…
- Chạy thử truy vấn mẫu
- Hoàn thành bài tập (0/2)