트랜잭션 올바르게 사용하기
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는 효과가 없습니다.