लारवेल एलक्विंट ओआरएम ट्रांजैक्शंस


96

एलोक्वेंट ओआरएम काफी अच्छा है, हालांकि मैं सोच रहा हूं कि क्या पीडीओ के रूप में उसी तरह से सहज तरीके से MySQL लेनदेन को सेटअप करने का एक आसान तरीका है, या अगर मुझे यह संभव करने के लिए ओआरएम का विस्तार करना होगा?

जवाबों:


165

तुम यह केर सकते हो:

DB::transaction(function() {
      //
});

बंद के अंदर सब कुछ एक लेनदेन के भीतर निष्पादित करता है। यदि कोई अपवाद होता है तो यह स्वचालित रूप से रोलबैक हो जाएगा।


1
क्लोजर के अंदर मैं एक कक्षा में प्रश्नों को कॉल कर सकता हूं? यह काम करेगा?
राफेल सूफराज

अफसोस की बात है कि यह मेरे लिए काम नहीं कर रहा है अगर मैं विभिन्न मॉडलों का उदाहरण बना रहा हूं जो अपने स्वयं के प्रासंगिक तरीकों में रिकॉर्ड जमा कर रहे हैं।
वोलेटिल 3

अगर मैं अपने लेन-देन (त्रुटि संदेश, आदि पैदा करने के लिए) के अंदर अपवाद को पकड़ता हूं, तो क्या मुझे रोल-अप होने के अपवाद को फिर से छोड़ना होगा?
एलेक्सव

3
अच्छा जवाब लेकिन कुछ बातों ने मुझे पकड़ा: 1. आपको "DB का उपयोग करें?" ऐसा करने के लिए अपने मॉडल फ़ाइल के शीर्ष पर 2। जेएस के विपरीत, आपको मूल रूप से स्थानीय चर तक पहुंच प्राप्त नहीं होती है जब तक कि आप उन्हें स्पष्ट रूप से पास नहीं करते हैं, आपको इस प्रकार "उपयोग" निर्माण को जोड़ने की आवश्यकता है ... डीबी :: लेनदेन (फ़ंक्शन () का उपयोग करें ($ उपयोगकर्ता) {... सामान का संदर्भ $ उपयोगकर्ता ...});
पोल्सनबी

Discussed in more detail hereलिंक मर चुका है।
शाम

100

यदि आपको अनाम कार्य पसंद नहीं हैं:

try {
    DB::connection()->pdo->beginTransaction();
    // database queries here
    DB::connection()->pdo->commit();
} catch (\PDOException $e) {
    // Woopsy
    DB::connection()->pdo->rollBack();
}

अद्यतन : लार्वा 4 के लिए, pdoवस्तु अब तक सार्वजनिक नहीं है:

try {
    DB::beginTransaction();
    // database queries here
    DB::commit();
} catch (\PDOException $e) {
    // Woopsy
    DB::rollBack();
}

15
आप शॉर्टकट मेथड DB::beginTransaction()& DB::commit()& का भी उपयोग कर सकते हैं DB::rollback()। यह थोड़ा क्लीनर होगा।
फ़्लोरी

2
कृपया @Flori सुझाव का उपयोग करने के लिए अपडेट करें। यह क्लीनर है। इसके अलावा, नए उत्तर को ऊपर की ओर ले जाने से आपका उत्तर कम भ्रमित हो जाएगा। दूसरे के लिए वापस आने से पहले मैंने पहली विधि का उपयोग किया।
ठंढाईदार

लारवेल के पुराने संस्करण के लिए, आपको आवश्यकता हो सकती है:DB::connection()->getPdo()->beginTransaction();
इसके बजाय

मुझे व्यक्तिगत रूप से लगता DB::transactionहै कि कॉलबैक के साथ भी क्लीनर है, लेकिन दोष यह है कि यदि आपको अलग-अलग अपवादों के लिए अलग-अलग हैंडलर निर्दिष्ट करने की आवश्यकता है, तो आपको तकनीक / तकनीक पकड़ने के लिए वापस जाना होगा
OzzyTheGiant

33

अगर आप एलोक्वेंट का उपयोग करना चाहते हैं, तो आप इसका भी उपयोग कर सकते हैं

यह मेरी परियोजना से सिर्फ नमूना कोड है

        /* 
         * Saving Question
         */
        $question = new Question;
        $questionCategory = new QuestionCategory;

        /*
         * Insert new record for question
         */
        $question->title = $title;
        $question->user_id = Auth::user()->user_id;
        $question->description = $description;
        $question->time_post = date('Y-m-d H:i:s');

        if(Input::has('expiredtime'))
            $question->expired_time = Input::get('expiredtime');

        $questionCategory->category_id = $category;
        $questionCategory->time_added = date('Y-m-d H:i:s');

        DB::transaction(function() use ($question, $questionCategory) {

            $question->save();

            /*
             * insert new record for question category
             */
            $questionCategory->question_id = $question->id;
            $questionCategory->save();
        });

question->idलेन-देन कॉलबैक पर अभिव्यक्ति शून्य देता है।
क्रिस्टोस पापोलस

@ChristosPapoulas का मतलब था, हम लेन-देन में ऑटो वेतन वृद्धि आईडी नहीं प्राप्त कर सकते हैं?
हैलोजिनजाई

26

यदि आप बंद होने से बचना चाहते हैं, और facades का उपयोग करके खुश हैं, तो निम्नलिखित चीजें अच्छी और साफ रहती हैं:

try {
    \DB::beginTransaction();

    $user = \Auth::user();
    $user->fill($request->all());
    $user->push();

    \DB::commit();

} catch (Throwable $e) {
    \DB::rollback();
}

यदि कोई कथन विफल हो जाता है, तो प्रतिबद्ध कभी नहीं मारा जाएगा, और लेनदेन प्रक्रिया नहीं करेगा।


यदि कोई कथन विफल हो जाता है, तो बाद के कथन नहीं चलेंगे। आपको अभी भी लेन-देन स्पष्ट रूप से वापस करने की आवश्यकता है।
जेसन

1
@ जेसन मैंने उत्तर को अपडेट कर दिया है। मैं दो दिमागों में था यदि मैं करूं, तो अधिकांश (सभी?) डेटाबेस इंजनों के लिए, जब कनेक्शन समाप्त हो जाता है, तो कोई भी ट्रांजेक्शनल प्रश्न समाप्त नहीं होगा। हालाँकि, मैं इस बात से सहमत हूँ कि आप क्या कह रहे हैं, और संभवतः स्पष्ट होने के लिए सबसे अच्छा है
क्रिस

18

मुझे यकीन है कि आप एक बंद समाधान की तलाश नहीं कर रहे हैं, इसे अधिक कॉम्पैक्ट समाधान के लिए आज़माएं

 try{
    DB::beginTransaction();

    /*
     * Your DB code
     * */

    DB::commit();
}catch(\Exception $e){
    DB::rollback();
}

10

किसी कारण से यह जानकारी कहीं भी मिलना काफी मुश्किल है, इसलिए मैंने इसे यहां पोस्ट करने का फैसला किया, जैसा कि मेरा मुद्दा, जबकि एलोकेंट लेनदेन से संबंधित, वास्तव में इसे बदल रहा था।

इस स्टैकओवरफ़्लो उत्तर को पढ़ने के बाद , मुझे एहसास हुआ कि मेरे डेटाबेस टेबल इनोबीडी के बजाय MyISAM का उपयोग कर रहे थे।

लेनवेल पर काम करने के लिए लेनदेन (या कहीं और जैसा लगता है), यह आवश्यक है कि आपकी तालिकाओं को InnoDB का उपयोग करने के लिए सेट किया गया हो

क्यों?

MySQL लेनदेन और परमाणु संचालन डॉक्स ( यहां ) उद्धृत करते हुए :

MySQL सर्वर (संस्करण 3.23-अधिकतम और सभी संस्करण 4.0 और ऊपर) InnoDB और BDB लेनदेन भंडारण इंजन के साथ लेनदेन का समर्थन करता है। InnoDB पूर्ण ACID अनुपालन प्रदान करता है। अध्याय 14, संग्रहण इंजन देखें। लेनदेन त्रुटियों के उपचार के संबंध में मानक SQL से InnoDB अंतर के बारे में जानकारी के लिए, अनुभाग 14.2.11, "InnoDB त्रुटि हैंडलिंग" देखें।

MySQL सर्वर (जैसे MyISAM) में अन्य nontransactional भंडारण इंजन "परमाणु संचालन" नामक डेटा अखंडता के लिए एक अलग प्रतिमान का पालन करते हैं। लेन-देन के संदर्भ में, MyISAM तालिकाओं को हमेशा ऑटोकॉमिट = 1 मोड में संचालित किया जाता है। परमाणु संचालन अक्सर उच्च प्रदर्शन के साथ तुलनीय अखंडता प्रदान करते हैं।

क्योंकि MySQL सर्वर दोनों प्रतिमानों का समर्थन करता है, आप यह तय कर सकते हैं कि क्या आपके अनुप्रयोग परमाणु संचालन की गति या ट्रांसेक्शनल सुविधाओं के उपयोग द्वारा सर्वोत्तम रूप से परोसे जाते हैं। यह चुनाव प्रति तालिका के आधार पर किया जा सकता है।


यह डीएमएल के लिए सच है, और डीडीएल के लिए हमेशा सच नहीं है।
येवगेनी अफानसेयेव

4

यदि कोई अपवाद होता है, तो लेनदेन स्वचालित रूप से रोलबैक होगा।

लारवेल बेसिक ट्रांजेक्शन फॉर्मेट

    try{
    DB::beginTransaction();

    /* 
    * SQL operation one 
    * SQL operation two
    ..................     
    ..................     
    * SQL operation n */


    DB::commit();
   /* Transaction successful. */
}catch(\Exception $e){       

    DB::rollback();
    /* Transaction failed. */
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.