Real Mysql 책에서 소개하는 데드락 상황을 라라벨 artisan tinker로 쉽게 재현하려고 한다.
(django manage shell에서는 데드락 상황을 만들수가 없다)
이 책에서는 총 4가지 패턴을 정리하고 있다.
위 4개 중 이번 글에서는 "외래키 관련"만 재현을 해보고자 한다.
Teacher - Student 각 2개의 모델이 있으며 하나의 Teacher가 여러개 Student를 가지는 일대다 관계 이다.
Schema::create('teachers', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 50)->comment('선생이름');
$table->integer('count')->default(0);
$table->timestamps();
});
Schema::create('students', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('teacher_id');
$table->string('name', 30)->comment('학생이름');
$table->timestamps();
$table->foreign('teacher_id')->references('id')
->on('teachers');
$teacher = Teacher::where('id', 1)->first()
트랙잭션 1 | 트랙잭션 2 |
DB::beginTransaction(); | DB::beginTransaction(); |
Student::create(['name'=> 't2', 'teacher_id' => 1]) | .... |
... | Student::create(['name'=> 't3', 'teacher_id' => 1]) |
$teacher = Teacher::where('id', 1)->first() | .... |
$teacher->count = 1 | .... |
$teacher->save() | .... |
.... | $teacher = Teacher::where('id', 1)->first() |
.... | $teacher->count = 1 |
.... | $teacher->save() |
데드락 발생 지정 |
데드락 발생 시, 위 예시에서 2개의 트랙잭션이 모두 다 실패가 되는게 아니라 하나가 실패하면 나머지 하나는 잘 수행이 된다. 트랙잭션이 실패가 되면 에로 로그가 생성 되지만 한쪽만 실패되고 한쪽은 에러 없이 잘 수행하기에 어느 트랜잭션 끼리 맞물린지 파악하기 어려운 면이 있다.
나머지 3가지 케이스 관련해서는 추후 정리하고자 한다.