ORM yang fasih cukup bagus, meskipun saya bertanya-tanya apakah ada cara mudah untuk mengatur transaksi MySQL menggunakan innoDB dengan cara yang sama seperti PDO, atau apakah saya harus memperluas ORM untuk memungkinkannya?
Jawaban:
Kamu bisa melakukan ini:
DB::transaction(function() {
//
});
Segala sesuatu di dalam Penutupan dijalankan dalam transaksi. Jika pengecualian terjadi, ia akan melakukan rollback secara otomatis.
Discussed in more detail here
link sudah mati.
Jika Anda tidak menyukai fungsi anonim:
try {
DB::connection()->pdo->beginTransaction();
// database queries here
DB::connection()->pdo->commit();
} catch (\PDOException $e) {
// Woopsy
DB::connection()->pdo->rollBack();
}
Pembaruan : Untuk laravel 4, pdo
objeknya tidak lagi publik jadi:
try {
DB::beginTransaction();
// database queries here
DB::commit();
} catch (\PDOException $e) {
// Woopsy
DB::rollBack();
}
DB::beginTransaction()
& DB::commit()
& DB::rollback()
. Itu akan sedikit lebih bersih.
DB::connection()->getPdo()->beginTransaction();
DB::transaction
dengan callback bahkan lebih bersih tetapi kekurangannya adalah jika Anda perlu menentukan penangan yang berbeda untuk pengecualian yang berbeda, Anda harus kembali untuk mencoba / menangkap teknik
Jika Anda ingin menggunakan Eloquent, Anda juga dapat menggunakan ini
Ini hanya contoh kode dari proyek saya
/*
* 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
ekspresi di balik transaksi kembali nol.
Jika Anda ingin menghindari penutupan, dan senang menggunakan fasad, hal-hal berikut ini menjaga agar tetap bagus dan bersih:
try {
\DB::beginTransaction();
$user = \Auth::user();
$user->fill($request->all());
$user->push();
\DB::commit();
} catch (Throwable $e) {
\DB::rollback();
}
Jika ada pernyataan yang gagal, komit tidak akan pernah berhasil, dan transaksi tidak akan diproses.
Saya yakin Anda tidak mencari solusi penutupan, coba ini untuk solusi yang lebih ringkas
try{
DB::beginTransaction();
/*
* Your DB code
* */
DB::commit();
}catch(\Exception $e){
DB::rollback();
}
Untuk beberapa alasan cukup sulit untuk menemukan informasi ini di mana pun, jadi saya memutuskan untuk mempostingnya di sini, karena masalah saya, sementara terkait dengan transaksi Eloquent, benar-benar mengubah ini.
Setelah membaca jawaban stackoverflow INI , saya menyadari tabel database saya menggunakan MyISAM, bukan InnoDB.
Agar transaksi dapat berfungsi di Laravel (atau di mana pun yang terlihat), tabel Anda harus diatur untuk menggunakan InnoDB
Mengapa?
Mengutip dokumen Transaksi MySQL dan Operasi Atom (di sini ):
MySQL Server (versi 3.23-max dan semua versi 4.0 dan yang lebih baru) mendukung transaksi dengan mesin penyimpanan transaksional InnoDB dan BDB. InnoDB memberikan kepatuhan ACID penuh. Lihat Bab 14, Mesin Penyimpanan. Untuk informasi tentang perbedaan InnoDB dari SQL standar terkait dengan penanganan kesalahan transaksi, lihat Bagian 14.2.11, “Penanganan Kesalahan InnoDB”.
Mesin penyimpanan nontransaksional lainnya di Server MySQL (seperti MyISAM) mengikuti paradigma berbeda untuk integritas data yang disebut "operasi atom". Dalam istilah transaksional, tabel MyISAM secara efektif selalu beroperasi dalam mode autocommit = 1. Operasi atom sering menawarkan integritas yang sebanding dengan kinerja yang lebih tinggi.
Karena Server MySQL mendukung kedua paradigma tersebut, Anda dapat memutuskan apakah aplikasi Anda paling baik dilayani oleh kecepatan operasi atom atau penggunaan fitur transaksional. Pilihan ini dapat dibuat per tabel.
Jika terjadi pengecualian, transaksi akan dibatalkan secara otomatis.
Format transaksi 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. */
}