PHP
Working with Database Transactions in Eloquent
Ensure data integrity by using database transactions in Laravel Eloquent, allowing you to execute multiple database operations as a single, atomic unit.
// Example in a controller method or service class
use Illuminate\Support\Facades\DB;
use App\Models\Order;
use App\Models\Product;
use Exception;
class OrderService
{
public function createOrder(array $orderData, array $productQuantities)
{
DB::beginTransaction();
try {
// 1. Create the order
$order = Order::create([
'user_id' => $orderData['user_id'],
'total_amount' => 0 // Will be updated later
]);
$totalAmount = 0;
// 2. Attach products to the order and update inventory
foreach ($productQuantities as $productId => $quantity) {
$product = Product::find($productId);
if (!$product || $product->stock < $quantity) {
throw new Exception("Product {$productId} not found or insufficient stock.");
}
$order->products()->attach($productId, ['quantity' => $quantity, 'price' => $product->price]);
$product->decrement('stock', $quantity);
$totalAmount += ($product->price * $quantity);
}
// 3. Update the order total amount
$order->update(['total_amount' => $totalAmount]);
DB::commit(); // All operations successful, commit the transaction
return $order;
} catch (Exception $e) {
DB::rollBack(); // Something went wrong, rollback all operations
// Optionally, log the error or re-throw
throw $e;
}
}
}
// Using the service in a controller:
// $orderService = new OrderService();
// try {
// $order = $orderService->createOrder(
// ['user_id' => 1],
// [1 => 2, 3 => 1] // Product ID => Quantity
// );
// return response()->json(['message' => 'Order placed successfully', 'order_id' => $order->id]);
// } catch (Exception $e) {
// return response()->json(['error' => $e->getMessage()], 400);
// }
How it works: This snippet demonstrates how to use database transactions in Laravel Eloquent to ensure data consistency. By wrapping multiple database operations within `DB::beginTransaction()`, `DB::commit()`, and `DB::rollBack()`, you guarantee that either all operations succeed and are persisted, or if any error occurs, all changes are undone. This is crucial for complex operations like creating an order, where inventory, order details, and related items must be updated atomically.