Memahami penguncian
Kontrol Konkurensi Multi-Versi (MVCC) menyediakan pengaturan konkurensi yang sesuai untuk sebagian besar skenario. Namun, jika aplikasi memerlukan kunci tertentu yang mengontrol dengan tepat baris mana yang terpengaruh dan dengan tingkat kunci tertentu, mode kunci eksplisit memungkinkan kontrol terperinci ini.
Di Azure Database for PostgreSQL, ada tiga jenis kunci eksplisit, kunci tingkat tabel, kunci tingkat baris, dan kunci tingkat halaman. Transaksi awal meminta kunci dan, jika diterima, kunci yang diminta menjadi kunci yang ada. Jika transaksi lain mencoba mengambil kunci pada data yang sama, kunci akan diberikan jika tidak berkonflik dengan transaksi asli.
Misalnya, dua transaksi dapat mengkueri data yang sama secara bersamaan dengan pernyataan SELECT. Permintaan ini akan menggunakan kunci ACCESS SHARE dan keduanya akan diizinkan. Dalam skenario lain, satu transaksi mengkueri data dengan pernyataan SELECT dan kunci ACCESS SHARE, tetapi pada saat yang sama transaksi lain mencoba menghilangkan tabel yang sama. Menghapus tabel memerlukan kunci ACCESS EXCLUSIVE, yang tidak akan diberikan dalam skenario ini.
Kunci tingkat tabel
Kunci tingkat tabel memperoleh kunci pada seluruh tabel, bahkan jika mereka memiliki ROW dalam namanya. Mengunci seluruh tabel mungkin diperlukan jika tabel itu sendiri sedang dimodifikasi, atau bisa lebih efisien daripada menerapkan banyak kunci pada tingkat baris.
Ada delapan jenis kunci tingkat tabel di Azure Database for PostgreSQL dan perintah SQL yang memperoleh jenis kunci ini adalah:
| Mode Kunci | Diperoleh oleh |
|---|---|
| AKSES BERBAGI | Perintah SELECT |
| BERBAGI BARIS | perintah SELECT FOR UPDATE dan SELECT FOR SHARE |
| DERET EKSKLUSIF | Perintah UPDATE, DELETE, dan INSERT |
| BAGIKAN PEMBARUAN EKSKLUSIF | MENGANALISIS, MEMBUAT INDEKS SECARA BERSAMAAN, MEMBUAT STATISTIK, MENGOMENTARI, PERINTAH REINDEX SECARA BERSAMAAN, beberapa perintah UBAH INDEKS dan UBAH TABEL, dan VAKUM (tidak PENUH) |
| BAGIKAN | Perintah CREATE INDEX (bukan perintah CONCURRENTLY) |
| AKSES BARIS EKSKLUSIF | Perintah CREATE TRIGGER dan beberapa perintah ALTER TABLE |
| EKSKLUSIF | REFRESH perintah TAMPILAN TERWUJUD SECARA BERSAMAAN |
| AKSES EKSKLUSIF | PERINTAH DROP TABLE, REINDEX, TRUNCATE, CLUSTER, REFRESH MATERIALIZED VIEW (bukan CONCURRENTLY), sebagian besar perintah ALTER INDEX dan ALTER TABLE, dan VACUUM FULL |
Setiap jenis kunci yang ada memblokir kunci lain yang diminta untuk diperoleh. Tabel berikut ini mencantumkan kunci apa yang memblokir kunci lain agar tidak diperoleh:
| -- | BERBAGI AKSES yang sudah ada | BERBAGI DATA yang SUDAH ADA | EKSKLUSIF UNTUK BARIS YANG BERLAKU | PEMBARUAN BERBAGI YANG SUDAH ADA EKSKLUSIF | Bagikan yang Ada | EXCL BARIS BERBAGI yang sudah ada | Eksklusif yang Tersedia | Akses Eksklusif yang Ada |
|---|---|---|---|---|---|---|---|---|
| BERBAGI AKSES yang Diminta | Diblokir | |||||||
| Permintaan Bagian Baris | Diblokir | Diblokir | ||||||
| Diminta BARIS EKSKLUSIF | Diblokir | Diblokir | Diblokir | Diblokir | ||||
| PEMBARUAN BERBAGI YANG DIMINTA EKSKLUSIF | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir | |||
| Yang Diminta untuk Dibagikan | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir | |||
| SHARE ROW EXCLUSIVE yang diminta | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir | ||
| Eksklusif Diminta | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir | |
| AKSES EKSKLUSIF YANG DIMINTA | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir | Diblokir |
Kunci tingkat baris
Kunci tingkat baris lebih terperinci dan hanya memengaruhi transaksi lain yang mengakses baris yang sama. Jenis kunci ini meningkatkan keserempakan, tetapi mengambil dan melepaskan banyak kunci berdampak negatif pada kinerja. Kunci tingkat baris secara otomatis diperoleh oleh PostgreSQL dan tidak diterapkan secara manual.
Ada empat jenis kunci tingkat baris di Azure Database for PostgreSQL dan mereka diperoleh tergantung jenis kunci lainnya yang perlu diblokir:
| -- | YANG ada UNTUK BERBAGI KUNCI | YANG ADA UNTUK DIBAGIKAN | ADA UNTUK TIDAK ADA PEMBARUAN KUNCI | Yang Ada untuk Diperbarui |
|---|---|---|---|---|
| DIMINTA UNTUK BERBAGI AKSES KUNCI | Diblokir | |||
| Diminta UNTUK BERBAGI | Diblokir | Diblokir | ||
| Diminta TANPA PEMBARUAN KUNCI | Diblokir | Diblokir | Diblokir | |
| Diminta untuk diperbarui | Diblokir | Diblokir | Diblokir | Diblokir |
Kunci tingkat halaman
Kunci tingkat halaman memengaruhi halaman data, yang biasanya terdiri dari beberapa baris. Meskipun proses PostgreSQL menggunakan kunci tingkat halaman, pengembang aplikasi biasanya tidak memerlukan jenis kunci ini.
Mengunci secara manual dan memonitor kunci saat ini
Untuk menerapkan kunci pada tingkat tabel secara manual, Anda dapat menggunakan perintah LOCK dengan mode kunci yang diperlukan. Perintah LOCK harus berada dalam transaksi dan kunci dilepaskan ketika transaksi selesai. Contohnya:
BEGIN TRANSACTION;
LOCK TABLE humanresources.department IN ROW EXCLUSIVE MODE;
COMMIT;
Untuk melihat kunci yang saat ini disimpan di database, gunakan pg_locks. Misalnya, untuk melihat semua kunci saat ini, gunakan perintah berikut:
SELECT * FROM pg_locks;