PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

क्या एक पोस्टग्रेज कमिटमेंट उस प्रक्रिया में मौजूद हो सकता है जिसमें एक अपवाद ब्लॉक है?

PL/pgSQL के त्रुटि प्रबंधन<का शब्दार्थ /ए> हुक्म दें कि:

इसे उप-लेनदेन का उपयोग करके कार्यान्वित किया जाता है, जो मूल रूप से savepoint के समान होते हैं। . दूसरे शब्दों में, जब आप निम्न PL/pgSQL कोड चलाते हैं:

BEGIN
  PERFORM foo();
EXCEPTION WHEN others THEN
  PERFORM handle_error();
END

...वास्तव में जो हो रहा है वह कुछ इस प्रकार है:

BEGIN
  SAVEPOINT a;
  PERFORM foo();
  RELEASE SAVEPOINT a;
EXCEPTION WHEN others THEN
  ROLLBACK TO SAVEPOINT a;
  PERFORM handle_error();
END

एक COMMIT ब्लॉक के भीतर इसे पूरी तरह से तोड़ देगा; आपके परिवर्तन स्थायी कर दिए जाएंगे, सेवपॉइंट को छोड़ दिया जाएगा, और अपवाद हैंडलर को वापस रोल करने का कोई तरीका नहीं छोड़ा जाएगा। परिणामस्वरूप, इस संदर्भ में कमिट की अनुमति नहीं है, और COMMIT को निष्पादित करने का प्रयास कर रहा है परिणामस्वरूप "एक उप-लेनदेन सक्रिय होने पर प्रतिबद्ध नहीं हो सकता" त्रुटि।

यही कारण है कि आप अपनी प्रक्रिया को raise notice 'B' चलाने के बजाय अपवाद हैंडलर पर जाते हुए देखते हैं :जब यह commit . तक पहुंच जाता है , यह एक त्रुटि फेंकता है, और हैंडलर इसे पकड़ लेता है।

हालांकि, यह काम करने के लिए काफी सीधा है। BEGIN ... END ब्लॉक को नेस्ट किया जा सकता है, और केवल EXCEPTION . के साथ ब्लॉक किया जा सकता है क्लॉज में सेवपॉइंट सेट करना शामिल है, इसलिए आप कमिट से पहले और बाद में कमांड को अपने अपवाद हैंडलर में लपेट सकते हैं:

create or replace procedure x_transaction_try() language plpgsql
as $$
declare
  my_ex_state text;
  my_ex_message text;
  my_ex_detail text;
  my_ex_hint text;
  my_ex_ctx text;
begin
  begin
    raise notice 'A';
  exception when others then
    raise notice 'C';
    GET STACKED DIAGNOSTICS
      my_ex_state   = RETURNED_SQLSTATE,
      my_ex_message = MESSAGE_TEXT,
      my_ex_detail  = PG_EXCEPTION_DETAIL,
      my_ex_hint    = PG_EXCEPTION_HINT,
      my_ex_ctx     = PG_EXCEPTION_CONTEXT
    ;
    raise notice '% % % % %', my_ex_state, my_ex_message, my_ex_detail, my_ex_hint, my_ex_ctx;
  end;

  commit;

  begin
    raise notice 'B';
  exception when others then
    raise notice 'C';
    GET STACKED DIAGNOSTICS
      my_ex_state   = RETURNED_SQLSTATE,
      my_ex_message = MESSAGE_TEXT,
      my_ex_detail  = PG_EXCEPTION_DETAIL,
      my_ex_hint    = PG_EXCEPTION_HINT,
      my_ex_ctx     = PG_EXCEPTION_CONTEXT
    ;
    raise notice '% % % % %', my_ex_state, my_ex_message, my_ex_detail, my_ex_hint, my_ex_ctx;
  end;      
end;
$$;

दुर्भाग्य से, यह त्रुटि संचालकों में बहुत अधिक दोहराव का कारण बनता है, लेकिन मैं इससे बचने का एक अच्छा तरीका नहीं सोच सकता।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ibatis के साथ निवेशन पर id कैसे लौटाएं (रिटर्निंग कीवर्ड के साथ)

  2. Postgresql अनुक्रम के लिए मानों की सूची कैसे निर्दिष्ट करें

  3. कैस्केड बनी रहती है डुप्लिकेट पंक्तियां बनाता है?

  4. आंतरिक जुड़ने वाली क्वेरी के साथ डुप्लिकेट को कैसे रोकें (पोस्टग्रेस)

  5. पोस्टग्रेएसक्यूएल अपडेट ट्रिगर