MERGE işlemi tek bir atomik DML işlemi olarak çalışır ve Oracle’da aşağıdaki şekilde işler:
- Hedef tablodaki ilgili satırlar için exclusive row lock (X lock) alır
- Kaynak tablodaki ilgili satırlar için shared lock (S lock) alır
- Tüm eşleşen ve eşleşmeyen kayıtlar için UPDATE veya INSERT işlemlerini gerçekleştirir
- İşlem commit edilene kadar locklar tutulur
Bu nedenle:
- Tek bir MERGE statement’ı hedef tablodaki tüm eşleşen satırları aynı anda kilitler
- Loop içinde yapıldığında her iterasyonda sadece o anki satır için lock alınır ve işlem biter bitmez serbest bırakılır
Örnek olarak açıklayalım:
-- Tek MERGE - Tüm kayıtlar aynı anda locklanır
MERGE INTO hedef_tablo h
USING kaynak_tablo k
ON (h.id = k.id)
WHEN MATCHED THEN UPDATE ...
WHEN NOT MATCHED THEN INSERT ...;
-- Loop ile MERGE - Her satır ayrı ayrı locklanır
FOR r IN (SELECT * FROM kaynak_tablo) LOOP
MERGE INTO hedef_tablo h
USING (SELECT r.* FROM dual) k
ON (h.id = k.id)
WHEN MATCHED THEN UPDATE ...
WHEN NOT MATCHED THEN INSERT ...;
END LOOP;
Bu davranışın sonuçları:
- Performans:
- Tek MERGE genelde daha hızlıdır çünkü tek bir DML işlemi yapılır
- Ancak çok sayıda satır varsa ve concurrent erişim önemliyse loop yaklaşımı daha uygun olabilir
2. Kilitleme ve Concurrency:
- Tek MERGE diğer sessionların erişimini daha uzun süre engeller
- Loop yaklaşımı daha basit locking sağlar ve eş zamanlı erişime daha uyumludur
3. Deadlock Riski:
- Tek MERGE’de deadlock riski daha yüksektir çünkü çok sayıda lock aynı anda alınır
- Loop yaklaşımında risk daha düşüktür çünkü locklar sırayla alınıp bırakılır
Bu nedenle, özellikle yoğun eş zamanlı erişim olan sistemlerde ve büyük veri setlerinde loop içinde MERGE yapmak daha güvenli bir yaklaşım olabilir. Ancak her durumda performans ve eş zamanlı ihtiyaçlarına göre değerlendirme yapılmalıdır.