লারাভেল সুস্পষ্ট ওআরএম লেনদেন


97

স্পষ্টতই ওআরএম বেশ সুন্দর, যদিও আমি ভাবছিলাম যে পিডিওর মতো একই ফ্যাশনে নির্দোষ ডিবি ব্যবহার করে মাইএসকিউএল লেনদেনগুলি সেটআপ করার কোনও সহজ উপায় আছে, বা এটি সম্ভব করার জন্য যদি আমাকে ওআরএম প্রসারিত করতে হয়?

উত্তর:


166

তুমি এটি করতে পারো:

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

বন্ধের ভিতরে থাকা সমস্ত কিছুই লেনদেনের মধ্যেই কার্যকর করে। যদি কোনও ব্যতিক্রম ঘটে তবে তা স্বয়ংক্রিয়ভাবে রোলব্যাক করবে।


4
ক্লোজারের ভিতরে আমি কি কোনও ক্লাসে প্রশ্নগুলি কল করতে পারি? এটা কি কাজ করবে?
রাফায়েল সৌফরাজ

দুঃখজনকভাবে আমার পক্ষে এটি কাজ করছে না যদি আমি বিভিন্ন মডেলের উদাহরণ তৈরি করি যারা তাদের নিজস্ব প্রাসঙ্গিক পদ্ধতিতে রেকর্ড সংরক্ষণ করে চলেছে।
ভোল্টিল 3

আমি যদি আমার লেনদেনের ভিতরে একটি ব্যতিক্রম (ত্রুটি বার্তাগুলি উত্পন্ন করার জন্য) ধরে রাখি তবে রোলব্যাকটি হওয়ার জন্য আমার কি ব্যতিক্রমটি পুনরায় প্রেরণ করা দরকার?
alexw

4
উত্তম উত্তর তবে কয়েকটি জিনিস আমাকে ধরে ফেলল: ১. আপনার "যুক্ত ডিবি ব্যবহার করুন" যুক্ত করতে হবে; এটি করার জন্য উদাহরণস্বরূপ আপনার মডেল ফাইলের শীর্ষে ২. জেএস থেকে ভিন্ন, আপনি প্যারেন্ট স্কোপগুলিতে স্থানীয় ভেরিয়েবলগুলিতে অ্যাক্সেস পাবেন না যদি না আপনি এগুলিকে স্পষ্টভাবে প্রবেশ করেন, আপনার এইভাবে "ব্যবহার" কনস্ট্রাক্ট যুক্ত করা দরকার ... ডিবি :: লেনদেন (ফাংশন () ব্যবহার ($ ব্যবহারকারী) {... স্টাফ রেফারেন্সিং $ ইউজার ...});
পলসনবি

Discussed in more detail hereলিঙ্ক মারা গেছে।
টমলপ্রড

101

আপনি যদি বেনামে ফাংশন পছন্দ না করেন:

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()। এটা একটু পরিস্কার করা হবে।
ফ্লুরি

4
@ ফ্লোরি পরামর্শটি আপডেট করতে দয়া করে আপডেট করুন। এটা পরিষ্কার। এছাড়াও, নতুন উত্তরটি উপরের দিকে সরানো আপনার উত্তরটিকে কম বিভ্রান্ত করবে। দ্বিতীয়টির জন্য ফিরে আসার আগে আমি প্রথম পদ্ধতিটি ব্যবহার করেছি।
হিমশীতল

লারাভেল-এর পুরানো সংস্করণের জন্য আপনার প্রয়োজন হতে পারে:DB::connection()->getPdo()->beginTransaction();
পরিবর্তে

আমি ব্যক্তিগতভাবে DB::transactionকলব্যাকটি আরও পরিচ্ছন্ন মনে করি তবে এর অপূর্ণতাটি হ'ল বিভিন্ন ব্যতিক্রমের জন্য আপনাকে যদি বিভিন্ন হ্যান্ডলারগুলি নির্দিষ্ট করতে হয় তবে আপনাকে কৌশলটি ধরতে / ধরতে ফিরে যেতে হবে
ওজজি দ্য জিয়েন্ট

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লেনদেন কলব্যাক এ অভিব্যক্তি শূন্য ফেরৎ।
ক্রিস্টোস পাপলাস

@ ক্রিসটোস পাপৌলাস বলতে কী বোঝাতে চেয়েছিলেন, আমরা লেনদেনে অটো ইনক্রিমেন্ট আইডি পেতে পারি না?
হ্যালোঞ্জিজি

30

আপনি যদি ক্লোজারগুলি এড়াতে এবং ফেইসড ব্যবহার করতে খুশি করতে চান তবে নিম্নলিখিত জিনিসগুলি সুন্দর এবং পরিষ্কার রাখে:

try {
    \DB::beginTransaction();

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

    \DB::commit();

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

যদি কোনও বিবৃতি ব্যর্থ হয় তবে প্রতিশ্রুতি কখনও আঘাত করবে না এবং লেনদেনটি প্রক্রিয়া করবে না।


যদি কোনও বিবৃতি ব্যর্থ হয়, পরবর্তী বিবৃতি চলবে না। আপনার এখনও স্পষ্টভাবে লেনদেনটি ফিরিয়ে আনতে হবে।
জেসন 13

4
@ জেসন আমি উত্তর আপডেট করেছি। আমি দুটি মনের মধ্যে ছিলাম, বেশিরভাগ (সমস্ত?) ডাটাবেস ইঞ্জিনের জন্য, যখন সংযোগটি বন্ধ হয়ে যায় এমন কোনও লেনদেনমূলক প্রশ্নের প্রতিশ্রুতিবদ্ধ হবে না তখন for তবে, আপনি যা বলছেন তার সাথে আমি একমত এবং সম্ভবত স্পষ্ট হওয়া ভাল
ক্রিস

19

আমি নিশ্চিত যে আপনি কোনও ক্লোজার সমাধান খুঁজছেন না, আরও কমপ্যাক্ট সমাধানের জন্য এটি চেষ্টা করুন

 try{
    DB::beginTransaction();

    /*
     * Your DB code
     * */

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

10

কোনও কারণে এই তথ্যটি কোথাও খুঁজে পাওয়া বেশ কঠিন, তাই আমি এটিকে এখানে পোস্ট করার সিদ্ধান্ত নিয়েছি, কারণ আমার ইস্যুটি, স্পষ্টতামূলক লেনদেনের সাথে সম্পর্কিত হয়ে ঠিক এই পরিবর্তন করছিল।

এই স্ট্যাকওভারফ্লো উত্তরটি পড়ার পরে , আমি বুঝতে পারি আমার ডাটাবেস টেবিলগুলি InnoDB এর পরিবর্তে মাইআইএসএএম ব্যবহার করছে।

লারাভেল (বা অন্য যে কোনও জায়গায় যেমন মনে হয়) তে লেনদেন কাজ করার জন্য আপনার টেবিলগুলি InnoDB ব্যবহার করার জন্য সেট করা দরকার

কেন?

মাইএসকিউএল লেনদেন এবং পারমাণবিক অপারেশন ডক্সের উদ্ধৃতি ( এখানে ):

মাইএসকিউএল সার্ভার (সংস্করণ 3.23-সর্বোচ্চ এবং সমস্ত সংস্করণ 4.0 এবং এর বেশি) ইনোডিবি এবং বিডিবি ট্রানজেকশনাল স্টোরেজ ইঞ্জিনগুলির সাথে লেনদেনকে সমর্থন করে। InnoDB সম্পূর্ণ ACID সম্মতি সরবরাহ করে। অধ্যায় 14, স্টোরেজ ইঞ্জিন দেখুন। লেনদেনের ত্রুটিগুলির চিকিত্সা সম্পর্কিত স্ট্যান্ডার্ড এসকিউএল থেকে ইনোডিবি পার্থক্য সম্পর্কে তথ্যের জন্য বিভাগ 14.2.11, "ইনোডিবি ত্রুটি পরিচালনা" দেখুন।

মাইএসকিউএল সার্ভারের অন্যান্য অনিয়ন্ত্রিত স্টোরেজ ইঞ্জিনগুলি (যেমন মাইআইএসএএম) "অ্যাটমিক অপারেশনস" নামক ডেটা অখণ্ডতার জন্য একটি পৃথক দৃষ্টান্ত অনুসরণ করে। লেনদেনের ক্ষেত্রে, মাইআইএসএএম টেবিলগুলি কার্যকরভাবে অটোকোমিট = 1 মোডে কার্যকর হয়। পারমাণবিক অপারেশনগুলি প্রায়শই উচ্চ কার্যকারিতার সাথে তুলনীয় অখণ্ডতা সরবরাহ করে।

মাইএসকিউএল সার্ভার উভয় দৃষ্টান্ত সমর্থন করে, তাই আপনি সিদ্ধান্ত নিতে পারেন যে আপনার অ্যাপ্লিকেশনগুলি পারমাণবিক ক্রিয়াকলাপের গতি বা লেনদেনের বৈশিষ্ট্যগুলির ব্যবহারের দ্বারা সর্বোত্তমভাবে পরিবেশন করা হয়েছে। এই পছন্দটি প্রতি টেবিলের ভিত্তিতে করা যেতে পারে।


এটি ডিএমএলের জন্য সত্য, এবং সর্বদা ডিডিএলের ক্ষেত্রে সত্য নয়।
ইয়েভেগেনি আফানসিয়েভ

4

যদি কোনও ব্যতিক্রম ঘটে থাকে তবে লেনদেনটি স্বয়ংক্রিয়ভাবে রোলব্যাক করবে।

লারাভেল বেসিক লেনদেনের ফর্ম্যাট

    try{
    DB::beginTransaction();

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


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

    DB::rollback();
    /* Transaction failed. */
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.