PDO Transactions
Also Known As
PDO beginTransaction
PDO commit rollback
database transactions PHP
TL;DR
PDO wraps multiple queries in an atomic unit — either all succeed or all roll back.
Explanation
beginTransaction() disables auto-commit. commit() writes all changes atomically. rollBack() undoes everything since beginTransaction(). PDO throws a PDOException if beginTransaction() is called when already in a transaction. Savepoints (SAVEPOINT name / ROLLBACK TO name) allow partial rollbacks within a transaction. MySQL requires InnoDB tables — MyISAM does not support transactions.
Diagram
sequenceDiagram
participant PHP
participant MySQL
PHP->>MySQL: beginTransaction()
PHP->>MySQL: UPDATE accounts SET balance=balance-100
PHP->>MySQL: UPDATE accounts SET balance=balance+100
alt success
PHP->>MySQL: commit()
MySQL-->>PHP: OK
else exception
PHP->>MySQL: rollBack()
MySQL-->>PHP: reverted
end
Common Misconception
✗ Calling beginTransaction() twice nests transactions. MySQL does not support nested transactions — the second beginTransaction() silently commits the first. Use SAVEPOINTs for nested logic.
Why It Matters
Without transactions, a crash mid-operation leaves the database in a partially updated state — money transferred but not credited, orders created without inventory decremented.
Common Mistakes
- Forgetting rollBack() in the catch block — failed transactions hold locks until the connection closes.
- Using MyISAM tables which silently ignore transaction boundaries.
- Opening long-running transactions that hold row locks and cause deadlocks under concurrency.
Avoid When
- Avoid long-running transactions — they hold row locks and cause deadlocks under concurrency.
- Do not open a transaction and then make external HTTP calls before committing — network failures leave transactions open.
When To Use
- Use transactions for any operation that modifies multiple rows or tables that must succeed or fail together.
- Use transactions for financial operations, inventory management, and any multi-step state change.
Code Examples
✗ Vulnerable
// No transaction — partial failure leaves DB inconsistent
$pdo->prepare('UPDATE accounts SET balance = balance - ? WHERE id = ?')
->execute([$amount, $fromId]);
// Exception here? $fromId debited, $toId never credited.
$pdo->prepare('UPDATE accounts SET balance = balance + ? WHERE id = ?')
->execute([$amount, $toId]);
✓ Fixed
$pdo->beginTransaction();
try {
$pdo->prepare('UPDATE accounts SET balance = balance - ? WHERE id = ?')
->execute([$amount, $fromId]);
$pdo->prepare('UPDATE accounts SET balance = balance + ? WHERE id = ?')
->execute([$amount, $toId]);
$pdo->commit();
} catch (\Throwable $e) {
$pdo->rollBack();
throw $e;
}
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
31 Mar 2026
Views
17
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Perplexity 6
Unknown AI 3
Google 2
ChatGPT 1
Ahrefs 1
SEMrush 1
Also referenced
How they use it
crawler 12
crawler_json 1
pre-tracking 1
Related categories
⚡
DEV INTEL
Tools & Severity
🟠 High
⚙ Fix effort: Low
⚡ Quick Fix
Wrap multi-step operations in beginTransaction() / commit() with a catch block that calls rollBack()
📦 Applies To
PHP 5.1+
web
cli
🔗 Prerequisites
🔍 Detection Hints
Multiple execute() calls without beginTransaction()/commit() wrapping
Auto-detectable:
✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Medium
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: Function
Tests: Update