Laravel - InnoDB에서 데드락 만들기

런던행·2021년 6월 1일
0

Laravel

목록 보기
1/3

Real Mysql 책에서 소개하는 데드락 상황을 라라벨 artisan tinker로 쉽게 재현하려고 한다.
(django manage shell에서는 데드락 상황을 만들수가 없다)
이 책에서는 총 4가지 패턴을 정리하고 있다.

  • 상호 거래 관련
  • 유니크 인덱스 관련
  • 외래키 관련
  • 서로 다은 인덱스를 통한 잠금

위 4개 중 이번 글에서는 "외래키 관련"만 재현을 해보고자 한다.

Teacher - Student 각 2개의 모델이 있으며 하나의 Teacher가 여러개 Student를 가지는 일대다 관계 이다.

Teacher 모델 스키마

        Schema::create('teachers', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name', 50)->comment('선생이름');
            $table->integer('count')->default(0);
            $table->timestamps();
        });
        

Student 모델 스키마

        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가지 케이스 관련해서는 추후 정리하고자 한다.

profile
unit test, tdd, bdd, laravel, django, android native, vuejs, react, embedded linux, typescript

0개의 댓글