Skip to content

트랜잭션 (TransactionManager)

트랜잭션은 문서 상태의 스냅샷을 찍고, 콘텐츠를 추측적으로 렌더링한 다음, 결과를 유지할지 버릴지 결정할 수 있게 합니다. 이는 "시도 후 맞추기" 레이아웃 로직의 주요 메커니즘입니다.

API 개요

메서드설명반환
startTransaction()현재 문서 상태의 스냅샷 찍기static
commitTransaction()스냅샷 삭제하고 모든 변경 사항 유지static
rollbackTransaction()문서를 스냅샷으로 복원static

세 메서드 모두 플루언트 체이닝을 위해 static을 반환합니다.

작동 방식

startTransaction()을 호출하면 TransactionManager가 현재 문서 상태의 전체 복사본을 저장합니다 -- 커서 위치, 페이지 수, 콘텐츠 버퍼, 내부 카운터. 그런 다음 정상적으로 콘텐츠를 렌더링합니다.

  • 커밋은 저장된 스냅샷을 삭제합니다. 렌더링된 콘텐츠는 문서에 유지됩니다.
  • 롤백은 현재 상태를 저장된 스냅샷으로 교체합니다. startTransaction() 이후에 렌더링된 모든 것이 폐기됩니다.

기본 예제

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->addPage()
    ->setFont('Helvetica', '', 12);

// 현재 페이지에 블록이 맞는지 시도
$pdf->startTransaction();
$startPage = $pdf->getPage();
$pdf->multiCell(0, 6, $longText);

if ($pdf->getPage() > $startPage) {
    // 콘텐츠가 다음 페이지로 넘침 — 롤백하고 다른 방법 시도
    $pdf->rollbackTransaction();
    $pdf->addPage();
    $pdf->multiCell(0, 6, $longText);
} else {
    // 콘텐츠가 맞음 — 유지
    $pdf->commitTransaction();
}

활용 사례

남은 공간에 콘텐츠 맞추기

가장 일반적인 사용 사례는 콘텐츠를 커밋하기 전에 현재 페이지에 맞는지 확인하는 것입니다:

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->addPage()
    ->setFont('Helvetica', '', 10);

foreach ($sections as $section) {
    $pdf->startTransaction();
    $startPage = $pdf->getPage();

    $pdf->setFont('Helvetica', 'B', 14)
        ->cell(0, 8, $section['title'], newLine: true)
        ->setFont('Helvetica', '', 10)
        ->multiCell(0, 5, $section['body']);

    if ($pdf->getPage() > $startPage) {
        $pdf->rollbackTransaction();
        $pdf->addPage();
        $pdf->setFont('Helvetica', 'B', 14)
            ->cell(0, 8, $section['title'], newLine: true)
            ->setFont('Helvetica', '', 10)
            ->multiCell(0, 5, $section['body']);
    } else {
        $pdf->commitTransaction();
    }
}

콘텐츠 높이 측정

트랜잭션을 사용하여 실제로 배치하지 않고 콘텐츠가 차지할 수직 공간을 측정합니다:

php
$pdf->startTransaction();
$startY = $pdf->getY();
$pdf->multiCell(0, 5, $text);
$endY = $pdf->getY();
$height = $endY - $startY;
$pdf->rollbackTransaction();

// 이제 $height를 레이아웃 결정에 사용

중요한 제약 사항

중첩 불가

중첩 트랜잭션은 지원되지 않습니다. 트랜잭션이 이미 활성화된 상태에서 startTransaction()을 호출하면 예외가 발생합니다. 새 트랜잭션을 시작하기 전에 항상 커밋하거나 롤백하십시오.

성능 영향

트랜잭션은 문서 상태의 전체 스냅샷을 저장합니다. 많은 페이지와 큰 콘텐츠 버퍼가 있는 문서의 경우, 이는 일시적으로 메모리 사용량을 두 배로 늘릴 수 있습니다. 트랜잭션 블록을 가능한 한 작게 유지하십시오 -- 스냅샷, 렌더링, 결정, 그 다음 즉시 커밋 또는 롤백.

모범 사례

  • startTransaction()commitTransaction() / rollbackTransaction() 사이의 코드를 최소화하십시오.
  • 모든 startTransaction()이 정확히 하나의 commitTransaction() 또는 rollbackTransaction()과 짝을 이루도록 항상 보장하십시오.
  • 트랜잭션 블록 내에서 파일 I/O를 수행하거나 출력을 보내지 마십시오 -- 문서 변경만 롤백할 수 있습니다.
  • 전체 문서 생성을 트랜잭션으로 래핑하는 것보다 작은 섹션을 측정하는 것을 선호하십시오.

LGPL-3.0-or-later 라이선스로 배포됩니다.