मैं एक स्क्रिप्ट बनाना चाहता हूं जहां ऑरैकल सत्र जो डेडलॉक में जाते हैं, स्वचालित रूप से मारे जाते हैं
संपादित करें बेहतर तरीके से समझाया गया, कुछ वाक्यों को ठीक किया, और गतिरोध परिदृश्य को प्रदर्शित करने के लिए एक परीक्षण केस जोड़ा।
आप पहिया का फिर से आविष्कार क्यों करना चाहते हैं? Oracle स्वचालित रूप से एक गतिरोध का पता लगाता है, फेंकता है ORA-00060: deadlock detected while waiting for resource
, और गतिरोध में शामिल लेन-देन में से एक को वापस ले लेता है जिसे Oracle ने पीड़ित के रूप में तय किया था। पिछले सफल लेनदेन को वापस नहीं लिया गया है। डेडलॉक त्रुटि के बाद भी, यदि कोई प्रतिबद्धता जारी की जाती है, तो पिछला सफल लेनदेन किया जाएगा। इस समय, दूसरे सत्र का लेन-देन भी सफल होगा और आप एक प्रतिबद्धता जारी कर सकते हैं। ऐसा कुछ भी नहीं है जिसे आपको यहां स्पष्ट रूप से करने की आवश्यकता है। गतिरोध स्वचालित रूप से साफ़ हो जाते हैं -- आपको कभी भी साफ़ की आवश्यकता नहीं होती है उन्हें।
आमतौर पर, Oracle एक गतिरोध का पता लगाने में एक या दो सेकंड लेता है और त्रुटि फेंकता है।
जैसा कि यहां दिखाया गया है, आप एक साधारण परीक्षण मामले के साथ प्रयास कर सकते हैं:Oracle गतिरोध को समझना
आइए एक टेस्ट केस देखें -
SQL> CREATE TABLE t_test(col_1 NUMBER, col_2 NUMBER);
Table created
SQL> INSERT INTO t_test VALUES(1,2);
1 row inserted
SQL> INSERT INTO t_test VALUES(3,4);
1 row inserted
SQL> COMMIT;
Commit complete
SQL> SELECT * FROM t_test;
COL_1 COL_2
---------- ----------
1 2
3 4
प्रत्येक लेन-देन के समय पर ध्यान दें, बेहतर समझ के लिए मैंने समय पर समय निर्धारित किया है।
सत्र :1
12:16:06 SQL> UPDATE t_test SET col_1 = 5 WHERE col_2=2;
1 row updated.
Elapsed: 00:00:00.00
सत्र :2
12:16:04 SQL> UPDATE t_test SET col_1 = 6 WHERE col_2=4;
1 row updated.
Elapsed: 00:00:00.00
12:16:31 SQL> UPDATE t_test SET col_1 = 7 WHERE col_2=2;
इस समय, सत्र 2 प्रतीक्षारत रहता है ।
सत्र :1
12:16:15 SQL> UPDATE t_test SET col_1 = 8 WHERE col_2=4;
इस समय, सत्र 2 गतिरोध का शिकार है, सत्र 1 अभी भी इंतजार कर रहा है।
आइए सत्र 2 . से सत्र विवरण देखें -
12:22:15 SQL> select sid,status,program,sql_id, state, wait_class, blocking_session_status, event from v$session where schemaname='LALIT' and program='sqlplus.exe';
SID STATUS PROGRAM SQL_ID STATE WAIT_CLASS BLOCKING_SE EVENT
---------- -------- --------------- ------------- ------------------- --------------- ----------- ----------------------------------------------------------------
14 ACTIVE sqlplus.exe 60qmqpmbmyhxn WAITED SHORT TIME Network NOT IN WAIT SQL*Net message to client
134 ACTIVE sqlplus.exe 5x0zg4qwus29v WAITING Application VALID enq: TX - row lock contention
Elapsed: 00:00:00.00
12:22:18 SQL>
तो, v$session
सत्र 2 . में देखे जाने पर विवरण , यानी SID 14, का कहना है कि स्थिति सक्रिय . है .
आइए किसी अन्य सत्र से सत्र विवरण देखें, इसे सत्र 3 कहते हैं खातिर। याद रखें, सत्र 1 अभी भी इंतज़ार कर रहा है।
SQL> set time on timing on
12:24:41 SQL> select sid,status,program,sql_id, state, wait_class, blocking_session_status, event from v$session where schemaname='LALIT' and program='sqlplus.exe'
SID STATUS PROGRAM SQL_ID STATE WAIT_CLASS BLOCKING_SE EVENT
---------- -------- --------------- ------------- ------------------- ---------- ----------- ------------------------------
13 ACTIVE sqlplus.exe 60qmqpmbmyhxn WAITED SHORT TIME Network NOT IN WAIT SQL*Net message to client
14 INACTIVE sqlplus.exe WAITING Idle NO HOLDER SQL*Net message from client
134 ACTIVE sqlplus.exe 5x0zg4qwus29v WAITING Applicatio VALID enq: TX - row lock contention
n
Elapsed: 00:00:00.01
12:24:44 SQL>
इसलिए, अन्य सत्रों के लिए, सत्र 2 , यानी SID 14, निष्क्रिय . है . सत्र 1 अभी भी प्रतीक्षा कर रहा है घटना के साथ enq: TX - row lock contention
।
आइए सत्र 2 प्रतिबद्ध करें -
12:22:18 SQL> commit;
Commit complete.
Elapsed: 00:00:00.01
12:25:43 SQL>
इस समय, सत्र 1 . के लिए लॉक जारी किया जाता है , आइए सत्र 1 भी प्रतिबद्ध करें -
12:16:15 SQL> UPDATE t_test SET col_1 = 8 WHERE col_2=4;
1 row updated.
Elapsed: 00:08:27.29
12:25:43 SQL> commit;
Commit complete.
Elapsed: 00:00:00.00
12:26:26 SQL>
Elapsed: 00:08:27.29
सत्र 1 . दिखाता है सत्र 2 . तक इतनी देर तक प्रतीक्षा कर रहा था प्रतिबद्ध था।
संक्षेप में, यहां सत्र 1 की पूरी कहानी है -
12:16:06 SQL> UPDATE t_test SET col_1 = 5 WHERE col_2=2;
1 row updated.
Elapsed: 00:00:00.00
12:16:15 SQL> UPDATE t_test SET col_1 = 8 WHERE col_2=4;
1 row updated.
Elapsed: 00:08:27.29
12:25:43 SQL> commit;
Commit complete.
Elapsed: 00:00:00.00
12:26:26 SQL>
संक्षेप में, यहां सत्र 2 की पूरी कहानी है -
12:16:04 SQL> UPDATE t_test SET col_1 = 6 WHERE col_2=4;
1 row updated.
Elapsed: 00:00:00.00
12:16:31 SQL> UPDATE t_test SET col_1 = 7 WHERE col_2=2;
UPDATE t_test SET col_1 = 7 WHERE col_2=2
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
Elapsed: 00:00:24.47
12:22:15 SQL> select sid,status,program,sql_id, state, wait_class, blocking_session_status, event from v$session where schemaname='LALIT' and program='sqlplus.exe';
SID STATUS PROGRAM SQL_ID STATE WAIT_CLASS BLOCKING_SE EVENT
---------- -------- --------------- ------------- ------------------- --------------- ----------- ----------------------------------------------------------------
14 ACTIVE sqlplus.exe 60qmqpmbmyhxn WAITED SHORT TIME Network NOT IN WAIT SQL*Net message to client
134 ACTIVE sqlplus.exe 5x0zg4qwus29v WAITING Application VALID enq: TX - row lock contention
Elapsed: 00:00:00.00
12:22:18 SQL> commit;
Commit complete.
Elapsed: 00:00:00.01
12:25:43 SQL>
अब, देखते हैं कि कौन सा लेनदेन वास्तव में वापस ले लिया गया और कौन सा प्रतिबद्ध हो गया -
12:25:43 SQL> select * from t_test;
COL_1 COL_2
---------- ----------
5 2
8 4
Elapsed: 00:00:00.00
12:30:36 SQL>
निष्कर्ष
मेरी राय में, डेडलॉक के सत्र विवरण को जानने का सबसे अच्छा तरीका विवरण को यथासंभव वर्बोज़ के रूप में लॉग करना है। अन्यथा, डीबीए के लिए उचित जानकारी लॉग किए बिना जांच करना एक दुःस्वप्न है। उस मामले के लिए, यहां तक कि एक डेवलपर को वास्तविक डिज़ाइन दोष को सुधारने और ठीक करने के लिए इसे एक कठिन कार्य माना जाएगा यदि डेडलॉक त्रुटि विवरण मौखिक रूप से लॉग नहीं किया गया है। और एक लाइनर स्टेटमेंट के साथ समाप्त करने के लिए, डिज़ाइन दोष के कारण एक गतिरोध है, ओरेकल सिर्फ शिकार है और आवेदन अपराधी है। गतिरोध डरावने हैं, लेकिन वे डिज़ाइन की खामियों की ओर इशारा करते हैं जिन्हें जल्द या बाद में ठीक किया जाना चाहिए।