트랜잭션 올바르게 사용하기

webman의 데이터베이스 트랜잭션 사용법은 다른 프레임워크와 같습니다. 여기서는 주의해야 할 사항을 나열합니다.

코드 구조

코드 구조는 다른 프레임워크와 동일합니다. 예를 들어 Laravel 사용법(think-orm 유사)입니다.

Db::beginTransaction();
try {
    // ..비즈니스 처리略...

    Db::commit();
} catch (\Throwable $exception) {
    Db::rollBack();
}

여기서 특히 주의해야 할 점은 반드시 \Throwable을 사용해야 하며 절대 \Exception을 사용하면 안 됩니다. 비즈니스 처리 과정에서 Error가 발생할 수 있으며, 이는 Exception에 속하지 않기 때문입니다.

데이터베이스 연결

트랜잭션 중 모델을 조작할 때, 모델에 연결이 설정되어 있는지를 특히 주의해야 합니다. 모델에 연결이 설정되어 있다면 트랜잭션을 시작할 때 반드시 연결을 지정해야 하며, 그렇지 않으면 트랜잭션이 무효화됩니다(think-orm 유사). 예를 들어:

<?php

namespace app\model;
use support\Model;

class User extends Model
{

    // 여기에서 모델에 연결을 지정합니다.
    protected $connection = 'mysql';

    protected $table = 'users';

    protected $primaryKey = 'id';

}

모델에서 연결을 지정한 경우, 트랜잭션을 시작하고, 커밋하고, 롤백할 때 반드시 연결을 지정해야 합니다.

Db::connection('mysql')->beginTransaction();
try {
    // 비즈니스 처리
    $user = new User;
    $user->name = 'webman';
    $user->save();
    Db::connection('mysql')->commit();
} catch (\Throwable $exception) {
    Db::connection('mysql')->rollBack();
}

커밋되지 않은 트랜잭션의 요청 찾기

가끔 비즈니스 코드의 버그로 인해 특정 요청의 트랜잭션이 커밋되지 않을 수 있습니다. 어떤 컨트롤러 메소드에서 트랜잭션이 커밋되지 않았는지 빠르게 찾기 위해 webman/log 컴포넌트를 설치할 수 있습니다. 이 컴포넌트는 요청이 완료된 후 커밋되지 않은 트랜잭션이 있는지 자동으로 검사하고 로그를 기록합니다. 로그의 키워드는 Uncommitted transactions입니다.

webman/log 설치 방법

composer require webman/log

주의
설치 후에는 restart로 재시작해야 하며, reload는 효과가 없습니다.