Atomic Operations
Modify database values safely without race conditions. Use increment, decrement, multiply, and divide to let the database handle the math.
Why use Atomic Operations?
Fetching a value, modifying it in PHP, and saving it back creates a race condition. If two requests happen at once, updates can be lost.
$post->update(['views' => $views + 1]); // ❌ Unsafe
Atomic operations push the logic to the database. The database locks the row and calculates the new value reliably.
Numeric Operations
These operations work on Int and Float fields.
<?php
use Lib\Prisma\Classes\Prisma;
// 1. Increment: Add to a counter (e.g., Post Views)
$post = Prisma::getInstance()->post->update([
'where' => ['id' => 101],
'data' => [
'views' => ['increment' => 1],
'likes' => ['increment' => 5]
]
]);
// 2. Decrement: Remove from inventory
$product = Prisma::getInstance()->product->update([
'where' => ['sku' => 'TSHIRT-BLK-L'],
'data' => [
'stock' => ['decrement' => 1]
]
]);
<?php
// 3. Multiply: Apply a tax rate or scaling factor
$invoice = Prisma::getInstance()->invoice->update([
'where' => ['id' => 550],
'data' => [
'totalAmount' => ['multiply' => 1.15] // +15% Tax
]
]);
// 4. Divide: Split values or convert units
$stats = Prisma::getInstance()->stats->update([
'where' => ['day' => 'today'],
'data' => [
'averageTime' => ['divide' => 60] // Seconds to Minutes
]
]);
The "Set" Operation
The set operation is used to forcefully overwrite a value. While standard updates (e.g., 'status' => 'active') act as a "set", the explicit syntax is useful when updating lists or ensuring specific type handling in complex schemas.
<?php
// 5. Set: Force a specific value (Atomic replacement)
$user = Prisma::getInstance()->user->update([
'where' => ['id' => $userId],
'data' => [
'score' => ['set' => 0], // Reset score to 0
'tags' => ['set' => ['banned']] // Replace all tags
]
]);
Pro Tip
Use set when you need to completely replace a list or scalar and don't care about the previous value. Use increment when the change is relative to the current state.
Operation Reference
| Operation | Input Type | Use Case | Example Syntax |
|---|---|---|---|
| increment | Int, Float | Counting views, likes, steps. | ['increment' => 1] |
| decrement | Int, Float | Reducing inventory, spending credits. | ['decrement' => 50] |
| multiply | Int, Float | Compound interest, tax application. | ['multiply' => 1.05] |
| divide | Int, Float | Unit conversion, splitting costs. | ['divide' => 2] |
| set | Any | Hard resets, overwriting relations. | ['set' => 0] |
Best Practices
Concurrency
-
Always use
decrementfor stock/inventory. - Never calculate new values in PHP variables for shared data.
Data Types
-
Ensure your DB column allows negative values if
decrementcan go below zero. -
Use Float columns for
divideoperations to avoid rounding errors.