2012-10-08 17 views
48

क्या एक पोस्टग्रेएसक्यूएल फ़ंक्शन जैसे स्वचालित रूप से निम्नलिखित लेनदेन है?क्या पोस्टग्रेएसक्यूएल लेनदेन लेनदेन कर रहे हैं?

CREATE OR REPLACE FUNCTION refresh_materialized_view(name) 
    RETURNS integer AS 
$BODY$ 
DECLARE 
    _table_name ALIAS FOR $1; 
    _entry materialized_views%ROWTYPE; 
    _result INT; 
BEGIN   

    EXECUTE 'TRUNCATE TABLE ' || _table_name; 

    UPDATE materialized_views 
    SET last_refresh = CURRENT_TIMESTAMP 
    WHERE table_name = _table_name; 

    RETURN 1; 
END 
$BODY$ 
    LANGUAGE plpgsql VOLATILE SECURITY DEFINER; 


दूसरे शब्दों में, समारोह के निष्पादन के दौरान एक त्रुटि होती है तो कोई भी परिवर्तन हो जाएगा वापस किया जाए? यदि यह डिफ़ॉल्ट व्यवहार नहीं है, तो मैं फ़ंक्शन लेनदेन कैसे कर सकता हूं?

+4

आप इसका परीक्षण क्यों नहीं करते? बस रोलबैक करें और आप जानते हैं कि जवाब क्या है। यह "हां" होना चाहिए। –

+8

@ फ्रैंकहेइकेंस मेरा प्रश्न है "क्या परिवर्तनों के बाद ऑटोमेटिक रूप से लुढ़काया जाएगा", "रोलबैक निष्पादित होने पर परिवर्तनों को घुमाया जाएगा" –

+2

@ डॉन इस बात से अवगत रहें कि 'ट्रंकेट' है या कुछ है कुछ हद तक भयानक लेनदेन व्यवहार। मुझे विशिष्टताओं को याद नहीं है; pgsql- सामान्य अभिलेखागार खोजें। –

उत्तर

52

कार्य उन लेनदेन का हिस्सा हैं जिन्हें वे बुलाए जाते हैं। यदि लेनदेन वापस आ जाता है तो उनके प्रभाव वापस लुढ़क जाते हैं। लेनदेन करता है तो उनका काम करता है। फ़ंक्शन के भीतर कोई भी BEGIN ... EXCEPT ब्लॉक SAVEPOINT और ROLLBACK TO SAVEPOINT SQL कथन जैसे सेवपॉइंट्स (और हुड उपयोग के तहत) के रूप में काम करता है।

फ़ंक्शन या तो पूरी तरह से सफल हो जाता है या BEGIN ... EXCEPT त्रुटि प्रबंधन को छोड़कर पूरी तरह से विफल रहता है। यदि फ़ंक्शन के भीतर कोई त्रुटि उठाई जाती है और संभाली नहीं जाती है, तो फ़ंक्शन को कॉल करने वाले लेनदेन को निरस्त कर दिया जाता है। निरस्त लेनदेन प्रतिबद्ध नहीं हो सकते हैं, और यदि वे COMMIT को ROLLBACK के रूप में माना जाता है, तो त्रुटि में किसी भी अन्य लेनदेन के समान माना जाता है। का निरीक्षण करें:

regress=# BEGIN; 
BEGIN 
regress=# SELECT 1/0; 
ERROR: division by zero 
regress=# COMMIT; 
ROLLBACK 

देखें कि लेन-देन है, जो शून्य विभाजन की वजह से त्रुटि अवस्था में है, COMMIT पर वापस रोल?

आप एक स्पष्ट surounding लेन-देन के बिना एक समारोह को कॉल करते हैं नियम वास्तव में किसी अन्य पृष्ठ बयान के लिए के रूप में ही कर रहे हैं:

BEGIN; 
SELECT refresh_materialized_view(name); 
COMMIT; 

(यदि SELECT एक त्रुटि उठाया जहां COMMIT असफल हो जायेगी)।

पोस्टग्रेएसक्यूएल (अभी तक) कार्यों में स्वायत्त लेनदेन का समर्थन नहीं करता है, जहां प्रक्रिया/कार्य कॉलिंग लेनदेन से स्वतंत्र रूप से/रोलबैक कर सकता है। इसे dblink के माध्यम से एक नए सत्र का उपयोग करके अनुकरण किया जा सकता है।

+1

बहुत स्पष्ट स्पष्टीकरण। संक्षिप्त और बिंदु उदाहरणों के साथ अपने उत्तर को चित्रित करने के लिए विशेष धन्यवाद। – informatik01

17

जैसा कि पोस्टग्रेएसक्यूएल के बारे में मेरा ज्ञान क्रेग रिंगर से कम गहरा है, मैं एक छोटा जवाब देने की कोशिश करूंगा: हाँ।

यदि आप उस फ़ंक्शन को निष्पादित करते हैं जिसमें कोई त्रुटि है, तो डेटाबेस में कोई भी चरण प्रभावित नहीं होगा।

इसके अलावा, यदि आप PgAdmin में कोई क्वेरी निष्पादित करते हैं तो वही होता है।

उदाहरण के लिए, यदि आप एक प्रश्न में निष्पादित करें:

update your_table yt set column1 = 10 where yt.id=20; 

select anything_that_do_not_exists; 

पंक्ति में अद्यतन, your_table की id = 20 डेटाबेस में सहेजा नहीं जाएगा।

+0

स्पष्ट कुरकुरा उत्तर के लिए धन्यवाद! क्रेग के जवाब को पढ़ने के बाद मुझे अनिश्चित महसूस हो गया था। – stone

+0

क्रेग की तुलना में काफी बेहतर जवाब – Nulik

3

फ़ंक्शन स्तर में, यह अंतर्राष्ट्रीय नहीं है। दूसरे शब्दों में, फ़ंक्शन में प्रत्येक कथन एक एकल लेनदेन से संबंधित है, जो डिफ़ॉल्ट डीबी ऑटो प्रतिबद्ध मान है। ऑटो प्रतिबद्ध डिफ़ॉल्ट रूप से सच है। लेकिन वैसे भी है, तो आप का उपयोग कर

select schemaName.functionName()

ऊपर बयान 'का चयन schemaName समारोह कॉल करने के लिए की है।functionName() 'एक एकल लेनदेन है, चलिए लेनदेन टी 1 का नाम दें, और इसलिए फ़ंक्शन में सभी कथन लेनदेन T1 से संबंधित हैं। इस तरह, समारोह एक ही लेनदेन में है।

0

https://www.postgresql.org/docs/current/static/plpgsql-structure.html

यह इसी तरह के नाम एसक्यूएल के साथ PL/pgSQL में बयान समूहीकरण के लिए शुरू/अंत के उपयोग को लेकर भ्रमित न महत्वपूर्ण है लेन-देन पर नियंत्रण के लिए आदेश देता है। पीएल/पीजीएसक्यूएल के BEGIN/END केवल समूह के लिए हैं; वे लेनदेन शुरू या समाप्त नहीं करते हैं। कार्य और ट्रिगर प्रक्रियाओं को हमेशा बाहरी क्वेरी द्वारा स्थापित लेनदेन के भीतर निष्पादित किया जाता है - वे उस लेनदेन को शुरू या प्रतिबद्ध नहीं कर सकते हैं, क्योंकि उनके लिए निष्पादित करने के लिए कोई संदर्भ नहीं होगा। हालांकि, एक एक्सेप्शन क्लॉज युक्त एक ब्लॉक प्रभावी रूप से एक उप-ट्रांसलेशन बनाता है जो कर सकता है बाहरी लेनदेन को प्रभावित किए बिना वापस घुमाया जाना चाहिए। इसके बारे में अधिक जानकारी अनुभाग 39.6.6 देखें।

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