Skip to content

Transaction (TransactionManager)

Transaction cho phép bạn chụp snapshot trạng thái document, render nội dung thử nghiệm, rồi quyết định giữ hoặc hủy kết quả. Đây là cơ chế chính cho logic layout "thử-vừa".

Tổng quan API

MethodMô tảTrả về
startTransaction()Chụp snapshot trạng thái document hiện tạistatic
commitTransaction()Hủy snapshot và giữ mọi thay đổistatic
rollbackTransaction()Khôi phục document về snapshotstatic

Cả ba method trả về static để fluent chaining.

Cách hoạt động

Khi gọi startTransaction(), TransactionManager lưu bản sao đầy đủ trạng thái document hiện tại — vị trí con trỏ, số trang, buffer nội dung và counter nội bộ. Rồi bạn render nội dung bình thường.

  • Commit hủy snapshot đã lưu. Nội dung render được giữ trong document.
  • Rollback thay trạng thái hiện tại bằng snapshot đã lưu. Mọi thứ render từ startTransaction() bị hủy.

Ví dụ cơ bản

php
use Yeeefang\TcpdfNext\Core\Document;

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

// Thử vừa block trên trang hiện tại
$pdf->startTransaction();
$startPage = $pdf->getPage();
$pdf->multiCell(0, 6, $longText);

if ($pdf->getPage() > $startPage) {
    // Nội dung tràn sang trang tiếp — rollback và thử cách khác
    $pdf->rollbackTransaction();
    $pdf->addPage();
    $pdf->multiCell(0, 6, $longText);
} else {
    // Nội dung vừa — giữ lại
    $pdf->commitTransaction();
}

Trường hợp sử dụng

Vừa nội dung trong khoảng trống còn lại

Trường hợp phổ biến nhất là kiểm tra nội dung có vừa trang hiện tại trước khi commit:

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();
    }
}

Đo chiều cao nội dung

Dùng transaction để đo nội dung tiêu thụ bao nhiêu không gian dọc mà không thực sự đặt:

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

// Giờ dùng $height cho quyết định layout

Ràng buộc quan trọng

Không lồng nhau

Transaction lồng nhau không được hỗ trợ. Gọi startTransaction() khi transaction đang hoạt động sẽ throw exception. Luôn commit hoặc rollback trước khi bắt đầu transaction mới.

Ảnh hưởng hiệu suất

Transaction lưu snapshot đầy đủ trạng thái document. Cho tài liệu nhiều trang và buffer nội dung lớn, điều này có thể tạm thời gấp đôi bộ nhớ. Giữ block transaction nhỏ nhất có thể — snapshot, render, quyết định, rồi commit hoặc rollback ngay.

Thực hành tốt nhất

  • Giữ code giữa startTransaction()commitTransaction() / rollbackTransaction() tối thiểu.
  • Luôn đảm bảo mỗi startTransaction() được ghép đúng một commitTransaction() hoặc rollbackTransaction().
  • Không thực hiện I/O file hoặc gửi output trong block transaction — chỉ mutation document có thể rollback.
  • Ưu tiên đo từng phần nhỏ thay vì bọc toàn bộ quá trình tạo document trong transaction.

Phân phối theo giấy phép LGPL-3.0-or-later.