트랜잭션 (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를 수행하거나 출력을 보내지 마십시오 -- 문서 변경만 롤백할 수 있습니다.
- 전체 문서 생성을 트랜잭션으로 래핑하는 것보다 작은 섹션을 측정하는 것을 선호하십시오.