2009-10-15 39 views
7

Oracle'da güncelleme yapmak için bir satır kilitlenmişse, birinin test edebileceği bir yol var mı?Güncelleme için bir satırın kilitli olup olmadığını nasıl kontrol edersiniz?

select * from SOME_TABLE where THE_ID = 1000 for update; 

I THE_ID = 1000 ile satır kilitli olup olmadığını kontrol etmek isteyen bir kullanıcı grubu: Bir örnek olarak

, bir kullanıcı tarafından gerçekleştirilen aşağıdaki sorgu varsayalım. Bir güncelleme veya bir şey denerseniz, ikinci kullanıcı engellenir ve beklemeye devam eder (bunu istemez).

Ben de ikinci kullanıcı ile aşağıdaki sorguyu çalıştıran denedim: Ben aynı satırda iki kilit koyamaz beri bu başarısız olur

select * from SOME_TABLE where THE_ID = 1000 for update NOWAIT; 

. Ve öyle. "ORA-00054: kaynak meşgul ve NOWAIT belirtilen hata ile elde" alıyorum. Kilidin varlığını kontrol etmek için bu hatayı her zaman sayabilir miyim, yoksa bir satırın kilitlenip kilitlenmediğinin daha basit ve daha temiz bir yolu var mı?

Teşekkür ederiz!

+1

"ORA-00054: kaynak meşgul ve NOWAIT ile belirtildi" hatası alıyorsunuz - tablonuzun görebildiğinden emin misiniz? – SeriousCallersOnly

+0

@ SeriousCallersOnly: Teşekkürler, gerçekten "ORA-00054: kaynak meşgul ve NOWAIT belirtilen hata ile elde" yaşıyorum. ORA-00942, uygulamamın başka bir katmanı tarafından atıldı. Bunun için üzgünüm. Soruyu düzenleyeceğim. –

cevap

14

Sen İÇİN GÜNCELLEME NOWAIT ile bir yordam yazmak ve satır kilitlendiğinde bir hata iletisi döndürebilir:

SQL> CREATE OR REPLACE PROCEDURE do_something(p_id NUMBER) IS 
    2  row_locked EXCEPTION; 
    3  PRAGMA EXCEPTION_INIT(row_locked, -54); 
    4 BEGIN 
    5  FOR cc IN (SELECT * 
    6     FROM some_table 
    7     WHERE ID = p_id FOR UPDATE NOWAIT) LOOP 
    8  -- proceed with what you want to do; 
    9  NULL; 
10  END LOOP; 
11 EXCEPTION 
12  WHEN row_locked THEN 
13  raise_application_error(-20001, 'this row is locked...'); 
14 END do_something; 
15/

Procedure created 

Şimdi iki oturum ile küçük bir örnek yapalım: yapmalısınız

session_1> select id from some_table where id = 1 for update; 

     ID 
---------- 
     1 

session_2> exec do_something(1); 

begin do_something(1); end; 

ORA-20001: this row is locked... 
ORA-06512: at "VNZ.DO_SOMETHING", line 11 
ORA-06512: at line 2 

session_1> commit; 

Commit complete 

session_2> exec do_something(1); 

PL/SQL procedure successfully completed 
+0

Zaten SeriousCallersOnly yanıtladı Ben gerçekten ORA-00054 hatası yaşıyorum. Teşekkür ederim. Ama kilidi kontrol etmek için buna güvenebilir miyim? –

+0

@dpb: Bu mekanizmaya güvenebilirsiniz. Prosedürün aynı satırı kilitleyen iki seansla nasıl çalışacağını gösteren küçük bir örnek ekledim. –

1

Ne basit ne de temiz, ancak bilgi V$LOCK ve V$SESSION görünümlerinde kullanılabilir. Bununla birlikte, normal uygulama kodunuzun bir parçası olarak böyle bir şey kullanmanız gerektiğini düşünüyorsanız, tekrar düşünmeniz gerekir. Uygulamalar veritabanının nasıl kilitlendiğini umursamamaktadır. Kilitlenme halinde yaşıyorsanız, sorgularınızı yeniden yapılandırmanız gerekir.

İlgili konular