Transaction Script Pattern
Also Known As
procedural design
script-based architecture
stored procedure pattern
TL;DR
A pattern where each business operation is a single procedure — simple, linear, and appropriate for straightforward workflows without complex domain logic.
Explanation
Transaction Script (Martin Fowler, PoEAA) organises logic as a set of procedures — one function per business transaction. The procedure reads data, applies logic, and writes results. Simple, easy to understand, easy to trace. Best for: simple CRUD applications, scripting, reporting, and ETL. Problems at scale: duplicate logic across scripts, difficult to reuse, logic grows unwieldy as rules multiply. The contrast with Domain Model: Transaction Script = logic in procedures; Domain Model = logic in objects.
Common Misconception
✗ Transaction Script is always inferior to Domain Model — for simple workflows Transaction Script is cleaner and easier to understand than a full domain model; choose based on actual complexity.
Why It Matters
Applying Domain Model to a simple CRUD app is over-engineering; applying Transaction Script to a complex billing system produces an unmaintainable tangle of duplicated logic — matching pattern to complexity is the skill.
Common Mistakes
- Sticking with Transaction Script as the domain grows — recognise when duplication signals time to introduce a domain model.
- Long transaction scripts with 200+ lines — extract helpers but consider whether a domain model is needed.
- Business logic split between scripts and stored procedures — consolidate in one place.
- No service layer abstraction — transaction scripts directly calling SQL make testing difficult.
Code Examples
✗ Vulnerable
// Transaction script — appropriate for this simplicity:
function createUser(array $data): int {
$pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)')
->execute([$data['name'], $data['email']]);
return $pdo->lastInsertId();
}
// Fine for simple CRUD — no need for domain model complexity here
✓ Fixed
// Transaction script becoming unwieldy — time to refactor to domain model:
function processOrder(int $orderId): void {
// 50 lines: fetch order, check inventory, apply discount rules,
// calculate tax, charge payment, update inventory, send email,
// update loyalty points, generate invoice...
// Each rule duplicated in processReOrder(), processSubscriptionOrder()...
// Signal: extract Order domain object with these methods
}
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
16 Mar 2026
Edited
22 Mar 2026
Views
80
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
No pings yesterday
ChatGPT 26
Perplexity 19
Amazonbot 12
Google 7
Unknown AI 4
Ahrefs 1
Also referenced
How they use it
crawler 68
crawler_json 1
Related categories
⚡
DEV INTEL
Tools & Severity
🔵 Info
⚙ Fix effort: Low
⚡ Quick Fix
Use Transaction Script for simple operations where Domain Model is overkill — a PHP function that handles one use case from start to finish is fine for CRUD; refactor to Domain Model when business rules grow complex
📦 Applies To
any
web
cli
queue-worker
🔗 Prerequisites
🔍 Detection Hints
Simple CRUD over-engineered with DDD; transaction script grown too large with mixed business logic; use case functions tangling multiple concerns
Auto-detectable:
✗ No
phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: High
✗ Manual fix
Fix: High
Context: File
Tests: Update