2014-04-11 6 views
5

टेक विस्तारGolang - pgbouncer और लेन-देन के उपयोग

  • जाने संस्करण 1.2
  • जाने bmizerany/pq के लिए
  • postrgres पुस्तकालय

यह समस्या मुझे पागल गाड़ी चला रहा है और मैं आशा करती हूं किसी को हो जाएगा मदद करने में सक्षम

मैंने पोस्टग्रेज़ डेटाबेस से डेटा पढ़ने के लिए गोलांग में एक एप्लिकेशन विकसित किया है और प्रत्येक रिकॉर्ड के लिए http अनुरोध करें और फिर डेटाबेस अपडेट करें।

यह सब कुछ आसान है। हालांकि, हमारे पास जगह पर pgbouncer है। हमारे पास pgbouncer के लिए कॉन्फ़िगरेशन ऐसा है कि यह तैयार कथन का समर्थन नहीं करता है। चुपचाप तैयार प्रश्न में सभी प्रश्नों को लपेटें। Pgbouncer के लिए इस तरह का तरीका एक लेनदेन स्थापित करना है। डालने/अपडेट/हटाने जैसी चीजों के लिए यह सब ठीक है और अच्छा है।

चयन बयान मैं लेनदेन में यह लपेटकर हूँ के मामले में:

func TransactionQuery(db *sql.DB, baseQuery string) (rows *sql.Rows, code int, err error) { 
     tx, txErr := db.Begin() 
     if txErr != nil { 
      return nil, -1, txErr 
     } 

     selectStmt, prepErr := tx.Prepare(baseQuery) 
     if prepErr != nil { 
      return nil, -1, fmt.Errorf("Failed to prepare statment: %s Error: %v", baseQuery, prepErr) 
     } 

     defer func() { 
      if stmtErr := selectStmt.Close(); stmtErr != nil { 
       rows = nil 
       code = -2 
       err = fmt.Errorf("Failed to close statement: %v.", stmtErr) 
      } 
     }() 

     rows, err = selectStmt.Query() 
     if err != nil { 
      fmt.Errorf("Failed to retrieve data: %v", err) 
      return nil, -1, err 
     } 
     return rows, 0, nil 
    } 

गधा आप मैं बंद करने नहीं bnut शुरू कर रहा हूँ देख सकते हैं (HHMM, कि एक छोटे से बंद इंडेंट फेंक है लगता है) सौदा। इससे चीजों के पीजी पक्ष में समस्या होती है जहां हर चयन को 'लेनदेन में निष्क्रिय' स्थिति में छोड़ दिया जाता है।

मैंने tx.Commit() और tx.Rollback() की कोशिश की है और दोनों मामलों में मुझे त्रुटियां मिलती हैं:

"unknown response for simple query '3'" 

या

"unknown response for simple query 'D'" 

हो मैं सफलतापूर्वक जाओ में लेन-देन बंद? मैं हमारे pgbouncer.ini मुझे ड्राइवर लाइब्रेरी के लिए lib/pq करने के लिए स्विच करने के लिए अनुमति देने के लिए अपडेट होने की आशा करता हूं, लेकिन मैं मुझे यकीन नहीं है कि क्या यह सीधे इस मुद्दे की मदद करेगा।

तो, मैं टीएक्स ऑब्जेक्ट को सही तरीके से कैसे बंद करूं या हुड के तहत तैयार बयानों का उपयोग न करने के लिए बल देने का कोई तरीका है?

धन्यवाद नाथन

मैं थोड़ा चीजों को बदलने की कोशिश की है:

func TransactionQuery(db *sql.DB, baseQuery string) (rows *sql.Rows, code int, err error) { 
    tx, txErr := db.Begin() 
    if txErr != nil { 
     return nil, -1, txErr 
    } 

    /*selectStmt, prepErr := tx.Prepare(baseQuery) 
     if prepErr != nil { 
      return nil, -1, fmt.Errorf("Failed to prepare statment: %s Error: %v", baseQuery, prepErr) 
     } 
    */ 
    rows, err = tx.Query(baseQuery) 
    if err != nil { 
     fmt.Errorf("Failed to retrieve data: %v", err) 
     return nil, -1, err 
    } 

    /* if stmtErr := selectStmt.Close(); stmtErr != nil { 
      rows = nil 
      code = -2 
      err = fmt.Errorf("Failed to close statement: %v.", stmtErr) 
     }*/ 

    if txCloseErr := tx.Commit(); txErr != nil { 
     rows = rows 
     code = -3 
     err = txCloseErr 
    } 
    return rows, 0, nil 
} 

क्या मैं इस कोड के साथ लॉग में देखें:

pq: unexpected describe rows response: '3' 

हालांकि, मैं चाहिए इंगित करें कि यह दूसरी बार एक चयन कथन का प्रयास करते समय है। यह एप्लिकेशन बैच का चयन करता है, इसके साथ सौदा करता है और फिर बाद के बैच का चयन करता है। यह त्रुटि दूसरे चयन पर होती है। पहले चयन के साथ कोई समस्या नहीं है।

+0

क्या पोस्टग्रेज़ लॉग में कुछ भी है? समस्याग्रस्त बयान वहां लॉग किए जा सकते हैं जो आपको यह देखने की अनुमति देगा कि क्या आपको लगता है कि वास्तव में डीबी द्वारा प्राप्त किया जा रहा है। –

+0

मुझे इसके लिए डीबीए टीम से पूछना होगा क्योंकि मेरे पास उन लॉग तक पहुंच नहीं है। दिलचस्प बात यह है कि अगर मैं लेनदेन छोड़ देता हूं तो ऐप अपेक्षित के रूप में चलता है लेकिन लेनदेन राज्य में निष्क्रिय होने के साथ pgbouncer clogs। – nathj07

उत्तर

2

किसी और के लिए जो इसे हिट करता है मैंने इसे हल कर लिया है।

मैं जिस कोड को पंक्तियों को वापस कॉलिंग कोड (दिखाया नहीं गया) पर वापस कर रहा था। पंक्तियों को पढ़ने से पहले लेनदेन को बंद करना समस्या का कारण प्रतीत होता था। मैं पूरी तरह समझ नहीं पा रहा हूं कि अगर आप ऐसा करते हैं तो कृपया स्पष्ट करें।

अब मैं पंक्तियों और लेनदेन वस्तु दोनों को वापस कर देता हूं।फिर जब मैंने सभी पंक्तियों को पढ़ा है तो मैं लेनदेन को रोलबैक करता हूं। यह सब कुछ काम करता रहता है।

धन्यवाद नाथन

+1

जब आप लेनदेन को 'COMMIT' करते हैं, तो आप pgbouncer कह रहे हैं कि यह बैकएंड को दूसरे लेनदेन के लिए रीसायकल कर सकता है। 'BEGIN', क्वेरी, पंक्तियां पढ़ें, 'COMMIT' /' रोलबैक '। – Sean

0

Tx.Query sql.Rows है, जो परिणाम सेट करने के लिए एक कर्सर है का एक उदाहरण देता है। इस कर्सर को फिर से चालू करते समय डेटा को पुनर्प्राप्त नहीं किया गया है। कर्सर को फिर से चालू करते समय लेनदेन खुला रहता है।

यही कारण है कि लेनदेन बंद होने के बाद आप कर्सर को फिर से सक्रिय नहीं कर पाएंगे।

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