Skip to content

トランザクション(TransactionManager)

トランザクションを使用すると、ドキュメントの状態のスナップショットを取り、投機的にコンテンツをレンダリングし、結果を保持するか破棄するかを決定できます。これは「フィット確認」レイアウトロジックの主要なメカニズムです。

API概要

メソッド説明戻り値
startTransaction()現在のドキュメント状態のスナップショットを取得static
commitTransaction()スナップショットを破棄し、すべての変更を保持static
rollbackTransaction()ドキュメントをスナップショットの状態に復元static

3つのメソッドはすべてフルーエントチェーン用に 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() が必ず1つの commitTransaction() または rollbackTransaction() とペアになるようにしてください。
  • トランザクションブロック内でファイルI/Oや出力の送信を行わないでください。ロールバックできるのはドキュメントの変更のみです。
  • ドキュメント全体の生成をトランザクションでラップするのではなく、小さなセクションを測定することを推奨します。

LGPL-3.0-or-later ライセンスの下で公開されています。