답변:
다음과 같이 할 수 있습니다.
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
with 콜백이 더 깨끗 하다고 생각 하지만 단점은 다른 예외에 대해 다른 핸들러를 지정해야하는 경우 try / catch 기술로 돌아 가야한다는 것입니다
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
트랜잭션 콜백 의 표현식은 0을 반환합니다.
클로저를 피하고 싶고 파사드를 기꺼이 사용하고 싶다면 다음은 일을 멋지고 깨끗하게 유지합니다.
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();
}
어떤 이유로 어디서든이 정보를 찾기가 매우 어려웠 기 때문에 Eloquent 트랜잭션과 관련된 내 문제가 정확히 이것을 바꾸고 있었기 때문에 여기에 게시하기로 결정했습니다.
이 stackoverflow 답변을 읽은 후 데이터베이스 테이블이 InnoDB 대신 MyISAM을 사용하고 있음을 깨달았습니다.
트랜잭션이 Laravel (또는 보이는 다른 곳)에서 작동하려면 테이블이 InnoDB를 사용하도록 설정되어 있어야합니다.
왜?
MySQL 트랜잭션 및 원자 작업 문서 인용 ( 여기 ) :
MySQL Server (버전 3.23-max 및 모든 버전 4.0 이상)는 InnoDB 및 BDB 트랜잭션 스토리지 엔진과의 트랜잭션을 지원합니다. InnoDB는 완전한 ACID 준수를 제공합니다. 14 장, 스토리지 엔진을 참조하십시오. 트랜잭션 오류 처리와 관련하여 표준 SQL과 InnoDB의 차이점에 대한 자세한 내용은 14.2.11 절,“InnoDB 오류 처리”를 참조하십시오.
MySQL Server의 다른 비 트랜잭션 스토리지 엔진 (예 : MyISAM)은 "원자 적 작업"이라는 데이터 무결성에 대한 다른 패러다임을 따릅니다. 트랜잭션 측면에서 MyISAM 테이블은 효과적으로 항상 autocommit = 1 모드에서 작동합니다. 원자 적 작업은 종종 더 높은 성능과 비슷한 무결성을 제공합니다.
MySQL Server는 두 가지 패러다임을 모두 지원하므로 원자 적 작업의 속도 또는 트랜잭션 기능의 사용 중 애플리케이션이 최상의 서비스를 제공하는지 결정할 수 있습니다. 이 선택은 테이블별로 할 수 있습니다.