Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Bisakah saya melakukan MERGE atom di Oracle?

Ini bukan masalah dengan MERGE. Sebaliknya masalahnya terletak pada aplikasi Anda. Pertimbangkan prosedur tersimpan ini:

create or replace procedure upsert_t23 
    ( p_id in t23.id%type
      , p_name in t23.name%type )
is
    cursor c is
        select null 
        from t23
        where id = p_id;
    dummy varchar2(1);
begin
    open c;
    fetch c into dummy;
    if c%notfound then
        insert into t23 
            values (p_id, p_name);
    else
        update t23
             set name = p_name
             where id = p_id;
    end if;
 end;

Jadi, ini adalah PL/SQL yang setara dengan MERGE di T23. Apa yang terjadi jika dua sesi memanggilnya secara bersamaan?

SSN1>  exec upsert_t23(100, 'FOX IN SOCKS')

SSN2>  exec upsert_t23(100, 'MR KNOX')

SSN1 sampai di sana terlebih dahulu, tidak menemukan catatan yang cocok dan memasukkan catatan. SSN2 sampai di sana kedua tetapi sebelum SSN1 melakukan, tidak menemukan catatan, memasukkan catatan dan hang karena SSN1 memiliki kunci pada node indeks unik untuk 100. Ketika SSN1 melakukan SSN2 akan melemparkan pelanggaran DUP_VAL_ON_INDEX.

Pernyataan MERGE bekerja dengan cara yang persis sama. Kedua sesi akan memeriksa on (t23.id = 100) , tidak menemukannya dan turun ke cabang INSERT. Sesi pertama akan berhasil dan sesi kedua akan melemparkan ORA-00001.

Salah satu cara untuk menangani ini adalah dengan menerapkan penguncian pesimistis. Pada awal prosedur UPSERT_T23 kami mengunci tabel:

...
lock table t23 in row shared mode nowait;
open c;
...

Sekarang, SSN1 tiba, mengambil kunci dan melanjutkan seperti sebelumnya. Ketika SSN2 tiba tidak bisa mendapatkan kunci, jadi langsung gagal. Yang membuat frustasi bagi pengguna kedua tetapi setidaknya mereka tidak hang, ditambah lagi mereka tahu orang lain sedang mengerjakan rekaman yang sama.

Tidak ada sintaks untuk INSERT yang setara dengan SELECT ... FOR UPDATE, karena tidak ada yang bisa dipilih. Jadi tidak ada sintaks seperti itu untuk MERGE juga. Yang perlu Anda lakukan adalah memasukkan pernyataan LOCK TABLE di unit program yang mengeluarkan MERGE. Apakah ini mungkin untuk Anda tergantung pada kerangka kerja yang Anda gunakan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara mengkonfigurasi ulang Oracle 10g xe di Linux

  2. Kata Sandi Basis Data Kedaluwarsa dan Koneksi Masih Hidup

  3. Membuat Aplikasi Java di Oracle JDeveloper, Bagian 2

  4. Bagaimana cara menggunakan urutan Oracle yang ada untuk menghasilkan id dalam hibernasi?

  5. Entity Framework terhubung ke Oracle:ODP untuk .NET tidak mendukung waktu