Transaksi (TransactionManager)
Transaksi memungkinkan Anda mengambil snapshot dari state dokumen, me-render konten secara spekulatif, lalu memutuskan apakah akan mempertahankan atau membuang hasilnya. Ini adalah mekanisme utama untuk logika layout "coba-pas".
Ringkasan API
| Method | Deskripsi | Return |
|---|---|---|
startTransaction() | Ambil snapshot dari state dokumen saat ini | static |
commitTransaction() | Buang snapshot dan pertahankan semua perubahan | static |
rollbackTransaction() | Kembalikan dokumen ke snapshot | static |
Ketiga method mengembalikan static untuk fluent chaining.
Cara Kerja
Saat Anda memanggil startTransaction(), TransactionManager menyimpan salinan lengkap dari state dokumen saat ini — posisi kursor, jumlah halaman, buffer konten, dan counter internal. Anda kemudian me-render konten seperti biasa.
- Commit membuang snapshot yang tersimpan. Konten yang di-render tetap di dokumen.
- Rollback mengganti state saat ini dengan snapshot yang tersimpan. Semua yang di-render sejak
startTransaction()dibuang.
Contoh Dasar
use Yeeefang\TcpdfNext\Core\Document;
$pdf = Document::create()
->addPage()
->setFont('Helvetica', '', 12);
// Coba masukkan blok di halaman saat ini
$pdf->startTransaction();
$startPage = $pdf->getPage();
$pdf->multiCell(0, 6, $longText);
if ($pdf->getPage() > $startPage) {
// Konten overflow ke halaman berikutnya — rollback dan coba cara lain
$pdf->rollbackTransaction();
$pdf->addPage();
$pdf->multiCell(0, 6, $longText);
} else {
// Konten muat — pertahankan
$pdf->commitTransaction();
}Kasus Penggunaan
Memasukkan Konten di Ruang yang Tersisa
Kasus penggunaan paling umum adalah mengecek apakah konten muat di halaman saat ini sebelum meng-commit-nya:
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();
}
}Mengukur Tinggi Konten
Gunakan transaksi untuk mengukur berapa banyak ruang vertikal yang akan dikonsumsi konten tanpa benar-benar menempatkannya:
$pdf->startTransaction();
$startY = $pdf->getY();
$pdf->multiCell(0, 5, $text);
$endY = $pdf->getY();
$height = $endY - $startY;
$pdf->rollbackTransaction();
// Sekarang gunakan $height untuk keputusan layoutBatasan Penting
Tanpa Nesting
Transaksi bersarang tidak didukung. Memanggil startTransaction() saat transaksi sudah aktif akan melempar exception. Selalu commit atau rollback sebelum memulai transaksi baru.
Dampak Performa
Transaksi menyimpan snapshot lengkap dari state dokumen. Untuk dokumen dengan banyak halaman dan buffer konten besar, ini bisa menggandakan penggunaan memori untuk sementara. Jaga blok transaksi sekecil mungkin — snapshot, render, putuskan, lalu commit atau rollback segera.
Praktik Terbaik
- Jaga kode antara
startTransaction()dancommitTransaction()/rollbackTransaction()seminimal mungkin. - Selalu pastikan setiap
startTransaction()dipasangkan dengan tepat satucommitTransaction()ataurollbackTransaction(). - Jangan lakukan file I/O atau kirim output dalam blok transaksi — hanya mutasi dokumen yang bisa di-rollback.
- Lebih baik mengukur bagian kecil daripada membungkus seluruh pembuatan dokumen dalam transaksi.