2009-09-23 15 views
8

यह एक मूक सवाल की तरह लगता है, लेकिन मैं लेनदेन प्रबंधन पर ओरेकल अवधारणाओं गाइड में निम्न देखें:क्या ओरेकल एक त्रुटि पर लेनदेन वापस रोल करता है?

लेनदेन समाप्त होता है जब निम्न में से कोई होता है:

एक उपयोगकर्ता जारी करता है एक COMMIT या ROLLBACK बिना किसी सहेजने वाले खंड के बयान।

उपयोगकर्ता एक डीडीएल स्टेटमेंट चलाता है जैसे CREATE, DROP, RENAME, या ALTER। यदि वर्तमान लेनदेन में कोई भी DML कथन शामिल है, तो ओरेकल पहले लेन-देन करता है, और फिर डीडीएल कथन को एक नए, एकल कथन लेनदेन के रूप में चलाता है और करता है।

उपयोगकर्ता ओरेकल से डिस्कनेक्ट हो जाता है। वर्तमान लेनदेन प्रतिबद्ध है।

एक उपयोगकर्ता प्रक्रिया असामान्य रूप से समाप्त होती है। वर्तमान लेनदेन वापस लुढ़का है।

क्या मैं आखिरी बिंदु की व्याख्या करने के लिए हूं कि अगर मैं कोई प्रश्न पूछता हूं जिसमें कोई त्रुटि है, लेनदेन वापस लुढ़का जाएगा?

+0

वास्तव में, यह मेरे लिए एक बहुत ही रोचक सवाल की तरह लगता है। पोस्टग्रेस त्रुटि पर रोलबैक, और मुझे अक्सर यह परेशान लगता है (और आश्चर्य हुआ कि ओरेकल ने कुछ ऐसा किया था)। – jsight

+0

मुझे बताएं, यदि आप त्रुटियों पर रोलबैक नहीं चाहते हैं तो आप लेनदेन का उपयोग क्यों कर रहे हैं? यह लेनदेन के मुख्य उद्देश्यों में से एक है। –

+0

@ ओलिवर: मुझे जरूरी नहीं है कि वे चाहते हैं या नहीं चाहते हैं। मैं सिर्फ यह जानना चाहता हूं कि वे कैसे काम करते हैं। –

उत्तर

7

इस संदर्भ में "उपयोगकर्ता प्रक्रिया" क्लाइंट मशीन पर चल रही प्रक्रिया का जिक्र कर रही है जो ओरेकल से कनेक्शन बनाता है। दूसरे शब्दों में, यदि आप ओरेकल से कनेक्ट करने के लिए एप्लिकेशन ए (SQL*Plus, TOAD, आदि) का उपयोग कर रहे हैं, तो उपयोगकर्ता प्रक्रिया SQL*Plus, TOAD, आदि है। यदि लेनदेन के मध्य में होने पर उस उपयोगकर्ता की प्रक्रिया मर जाती है, तो वह लेनदेन वापस लुढ़का जाएगा। जैसे ही पीएमओएन पता चलता है कि ग्राहक की मृत्यु हो गई है, जिसमें कुछ समय लग सकता है - ओरेकल के लिए उपयोगकर्ता प्रक्रिया से उपयोगकर्ता प्रक्रिया की विफलता को अलग करने के लिए हमेशा तुच्छ नहीं होता है जो कि आदेश जारी नहीं कर रहा है क्षण।

1

मैं जस्टिन से सहमत हूं, उसकी अंतर्दृष्टि सही है। अतिरिक्त जानकारी जोड़ना: एप्लिकेशन डेवलपर के रूप में, यदि त्रुटियां होती हैं तो आपको स्पष्ट रूप से रोलबैक कमांड को कॉल करना चाहिए। इसका मतलब है, आपको उचित रूप से लेनदेन संबंधी ब्लॉक में समूहबद्ध विवरणों पर विचार करना चाहिए। विभिन्न प्रौद्योगिकियों द्वारा पारस्परिक ब्लॉक और रोलबैक को अलग-अलग संभाला जाता है, यह सुनिश्चित करने के लिए कुछ शोध योग्य है कि आप इसे अच्छी तरह समझते हैं।

12

यह एक दिलचस्प सवाल है!

जब ओरेकल में कोई त्रुटि आती है, तो यह वर्तमान स्टेटमेंट को लेनदेन नहीं करेगा, लेनदेन नहीं। एक कथन किसी भी शीर्ष-स्तरीय निर्देश है, यह एक SQL कथन (INSERT, अद्यतन ...) या एक पीएल/एसक्यूएल ब्लॉक हो सकता है।

इसका मतलब है कि जब एक बयान (उदाहरण के लिए जावा से बुलाया गया एक पीएल/एसक्यूएल प्रक्रिया) एक त्रुटि देता है, ओरेकल लेनदेन को उसी तर्कसंगत स्थिति में कॉल के पहले रखेगा। यह बेहद सहायक है, आपको आधा निष्पादित प्रक्रियाओं (**) के बारे में चिंता करने की ज़रूरत नहीं है।

This thread on AskTom covers the same topic:

[बयान] या तो पूरी तरह से होता है या यह पूरी तरह से नहीं होता है और तरीका है कि काम करता है डेटाबेस के तार्किक बराबर करता है:

begin 
    savepoint foo; 
    <<your statement>> 
exception 
    when others then rollback to foo; 
        RAISE; 
end; 

यह फीचर, मेरी राय में, किसी अन्य भाषा की तुलना में pl/sql में डेटाबेस कोड (*) लिखना बहुत आसान है।

(*) कोड जो ओरेकल डीबी के साथ इंटरैक्ट करता है, मुझे लगता है कि अन्य डीबीएमएस की मूल प्रक्रियात्मक भाषाओं में समान विशेषताएं हैं।

(**) ओरेकल में DDL are not transactional के बाद से यह केवल डीएमएल से संबंधित है। कुछ डीबीएमएस पैकेजों से सावधान रहें जो डेटा डिक्शनरी (जैसे DBMS_STATS) अपडेट करते हैं, वे अक्सर डीडीएल जैसे परिवर्तन करते हैं और जारी करते हैं। संदेह के मामले में documentation का संदर्भ लें।

अद्यतन:

SQL> CREATE TABLE T (a NUMBER); 

Table created 

SQL> CREATE OR REPLACE PROCEDURE p1 AS 
    2 BEGIN 
    3  -- this statement is successful 
    4  INSERT INTO t VALUES (2); 
    5  -- this statement will raise an error 
    6  raise_application_error(-20001, 'foo'); 
    7 END p1; 
    8/

Procedure created 

SQL> INSERT INTO t VALUES (1); 

1 row inserted 

SQL> EXEC p1; 

begin p1; end; 

ORA-20001: foo 
ORA-06512: at "VNZ.P1", line 5 
ORA-06512: at line 2 

SQL> SELECT * FROM t; 

     A 
---------- 
     1 

ओरेकल है: इस व्यवहार PL/SQL में सबसे महत्वपूर्ण अवधारणा में से एक है, मैं एक छोटा सा उदाहरण PL/SQL विवरणों की atomicity प्रदर्शित करने के लिए प्रदान करेगा पी 1 को कॉल करने से ठीक पहले लेनदेन को बिंदु पर वापस लाया। कोई आधा काम नहीं किया गया है। ऐसा लगता है कि प्रक्रिया पी 1 कभी नहीं बुलाया गया था।

+1

आप कथन और पीएल/एसक्यूएल ब्लॉक के बारे में गलत हैं। एक पीएल/एसक्यूएल ब्लॉक INSERT, अद्यतन या हटाए जाने से एक कथन नहीं है। यदि कोई पीएल/एसक्यूएल ब्लॉक एक त्रुटि फेंकता है और आपके कोड के टुकड़े की तरह कोई सेवपॉइंट हैंडलिंग नहीं है तो आपको आधा निष्पादित प्रक्रियाओं के बारे में चिंता करनी होगी। – Christian13467

+2

ईसाई, यह गलत है। यदि एक शीर्ष स्तर पीएल/एसक्यूएल ब्लॉक द्वारा एक अपवाद उठाया जाता है, जिसे क्लाइंट द्वारा बुलाया जाता है, तो उस ब्लॉक के आविष्कार से पहले बिंदु पर एक रोलबैक होता है (माना जाता है कि हस्तक्षेप पीएल/एसक्यूएल में कोई प्रतिबद्धता नहीं है)। –

+0

@ क्रिस्टियन: मैंने अपना जवाब अपडेट किया, उम्मीद है कि यह उस अवधारणा को स्पष्ट करेगा जो मैं समझाने की कोशिश कर रहा था। –

संबंधित मुद्दे