Eloquent ORM ค่อนข้างดีแม้ว่าฉันจะสงสัยว่ามีวิธีง่ายๆในการตั้งค่าธุรกรรม MySQL โดยใช้ innoDB แบบเดียวกับ PDO หรือไม่หรือฉันจะต้องขยาย ORM เพื่อให้เป็นไปได้
Eloquent ORM ค่อนข้างดีแม้ว่าฉันจะสงสัยว่ามีวิธีง่ายๆในการตั้งค่าธุรกรรม MySQL โดยใช้ innoDB แบบเดียวกับ PDO หรือไม่หรือฉันจะต้องขยาย ORM เพื่อให้เป็นไปได้
คำตอบ:
คุณสามารถทำได้:
DB::transaction(function() {
//
});
ทุกสิ่งที่อยู่ใน Closure จะดำเนินการภายในธุรกรรม หากมีข้อยกเว้นเกิดขึ้นจะย้อนกลับโดยอัตโนมัติ
Discussed in more detail here
ลิงค์ตายแล้ว
หากคุณไม่ชอบฟังก์ชั่นที่ไม่ระบุตัวตน:
try {
DB::connection()->pdo->beginTransaction();
// database queries here
DB::connection()->pdo->commit();
} catch (\PDOException $e) {
// Woopsy
DB::connection()->pdo->rollBack();
}
อัปเดต : สำหรับ laravel 4 pdo
วัตถุจะไม่เป็นสาธารณะอีกต่อไปดังนั้น:
try {
DB::beginTransaction();
// database queries here
DB::commit();
} catch (\PDOException $e) {
// Woopsy
DB::rollBack();
}
DB::beginTransaction()
& &DB::commit()
DB::rollback()
นั่นจะเป็นการทำความสะอาดเล็กน้อย
DB::connection()->getPdo()->beginTransaction();
DB::transaction
ด้วยการโทรกลับนั้นสะอาดกว่า แต่ข้อเสียคือหากคุณต้องการระบุตัวจัดการที่แตกต่างกันสำหรับข้อยกเว้นที่แตกต่างกันคุณจะต้องกลับไปใช้เทคนิคการลอง / จับ
หากคุณต้องการใช้ Eloquent คุณสามารถใช้สิ่งนี้ได้
นี่เป็นเพียงตัวอย่างโค้ดจากโครงการของฉัน
/*
* 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
แสดงออกในการทำธุรกรรมการเรียกกลับส่งกลับค่าศูนย์
หากคุณต้องการหลีกเลี่ยงการปิดและยินดีที่จะใช้อาคารสิ่งต่อไปนี้จะช่วยให้สิ่งต่างๆดีและสะอาด:
try {
\DB::beginTransaction();
$user = \Auth::user();
$user->fill($request->all());
$user->push();
\DB::commit();
} catch (Throwable $e) {
\DB::rollback();
}
หากคำสั่งใด ๆ ล้มเหลวการกระทำจะไม่ถูกกระทบและธุรกรรมจะไม่ดำเนินการ
ฉันแน่ใจว่าคุณไม่ได้มองหาวิธีการปิดลองวิธีนี้สำหรับโซลูชันที่กะทัดรัดกว่านี้
try{
DB::beginTransaction();
/*
* Your DB code
* */
DB::commit();
}catch(\Exception $e){
DB::rollback();
}
ด้วยเหตุผลบางประการมันค่อนข้างยากที่จะค้นหาข้อมูลนี้ได้ทุกที่ดังนั้นฉันจึงตัดสินใจโพสต์ที่นี่เนื่องจากปัญหาของฉันในขณะที่เกี่ยวข้องกับการทำธุรกรรมที่มีประสิทธิภาพกำลังเปลี่ยนแปลงสิ่งนี้อย่างสิ้นเชิง
หลังจากอ่านคำตอบสแตกโอเวอร์โฟลว์นี้ฉันรู้ว่าตารางฐานข้อมูลของฉันใช้ MyISAM แทน InnoDB
สำหรับการทำธุรกรรมบน Laravel (หรือที่อื่น ๆ ตามที่ดูเหมือน) จำเป็นต้องตั้งค่าตารางของคุณให้ใช้ InnoDB
ทำไม?
อ้างถึงเอกสารธุรกรรม MySQL และการดำเนินการปรมาณู ( ที่นี่ ):
MySQL Server (เวอร์ชัน 3.23-max และเวอร์ชัน 4.0 ขึ้นไปทั้งหมด) รองรับการทำธุรกรรมกับเอ็นจินหน่วยเก็บข้อมูลธุรกรรม InnoDB และ BDB InnoDB ให้การปฏิบัติตาม ACID อย่างสมบูรณ์ โปรดดูบทที่ 14 เครื่องมือจัดเก็บข้อมูล สำหรับข้อมูลเกี่ยวกับความแตกต่างของ InnoDB จาก SQL มาตรฐานที่เกี่ยวข้องกับการรักษาข้อผิดพลาดในการทำธุรกรรมโปรดดูหัวข้อ 14.2.11“ การจัดการข้อผิดพลาด InnoDB”
เอ็นจินการจัดเก็บข้อมูลแบบไม่ทำธุรกรรมอื่น ๆ ใน MySQL Server (เช่น MyISAM) เป็นไปตามกระบวนทัศน์ที่แตกต่างกันสำหรับความสมบูรณ์ของข้อมูลที่เรียกว่า "การดำเนินการของอะตอม" ในเงื่อนไขการทำธุรกรรมตาราง MyISAM จะทำงานในโหมด autocommit = 1 อย่างมีประสิทธิภาพเสมอ การดำเนินการของอะตอมมักให้ความสมบูรณ์เทียบเท่ากับประสิทธิภาพที่สูงกว่า
เนื่องจาก MySQL Server รองรับทั้งสองกระบวนทัศน์คุณจึงสามารถตัดสินใจได้ว่าแอปพลิเคชันของคุณจะได้รับการตอบสนองที่ดีที่สุดด้วยความเร็วของการดำเนินการของอะตอมหรือการใช้คุณสมบัติการทำธุรกรรม ตัวเลือกนี้สามารถทำได้แบบต่อโต๊ะ
หากมีข้อยกเว้นเกิดขึ้นธุรกรรมจะย้อนกลับโดยอัตโนมัติ
รูปแบบธุรกรรม Laravel Basic
try{
DB::beginTransaction();
/*
* SQL operation one
* SQL operation two
..................
..................
* SQL operation n */
DB::commit();
/* Transaction successful. */
}catch(\Exception $e){
DB::rollback();
/* Transaction failed. */
}