Ya dan Tidak - seperti biasa, itu tergantung. Dokumentasi tegas mengatakan bahwa:
Dengan kata lain, SELECT berbeda dari SELECT FOR UPDATE/DELETE/UPDATE.
Anda dapat membuat test case sederhana untuk mengamati perilaku tersebut:
Sesi 1
test=> START TRANSACTION;
START TRANSACTION
test=> SELECT * FROM test;
x
----
1
2
3
4
5
6
7
8
9
10
(10 rows)
test=> DELETE FROM test;
DELETE 10
test=>
Sekarang login di Sesi lain 2:
test=> START TRANSACTION;
START TRANSACTION
test=> SELECT * FROM test;
x
----
1
2
3
4
5
6
7
8
9
10
(10 rows)
test=> SELECT * FROM test WHERE x = 5 FOR UPDATE;
Setelah perintah terakhir SELECT ... FOR UPDATE
sesi 1 "hang" dan sedang menunggu sesuatu ......
Kembali ke sesi 1
test=> insert into test select * from generate_series(1,10);
INSERT 0 10
test=> commit;
COMMIT
Dan sekarang ketika Anda kembali ke sesi 2, Anda akan melihat ini:
test=> SELECT * FROM test WHERE x = 5 FOR UPDATE;
x
---
(0 rows)
test=> select * from test;
x
----
1
2
3
4
5
6
7
8
9
10
(10 rows)
Yaitu - SELECT
simple sederhana masih tidak melihat perubahan apa pun, sementara SELECT ... FOR UPDATE
tidak melihat bahwa baris telah dihapus. Namun tidak melihat baris baru disisipkan oleh sesi 1
Sebenarnya urutan yang Anda lihat adalah:
- proses A memulai transaksinya
- proses A menghapus semuanya dari tabel T
- proses B memulai transaksinya
- proses B mencoba memilih untuk pembaruan pada satu baris dalam tabel T
- proses B "hang" dan menunggu hingga sesi A melakukan commit atau rollback
- proses A mengisi ulang tabel T dari data yang masuk
- proses A melakukan transaksinya
- proses B muncul kosong (0 baris- setelah sesi A komit) dan memanggil rollback