Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here
Tutorial Free

Database Transactions in Laravel: 5 Open-Source Examples

December 06, 2022
5 min read

Database Transactions are essential if you want to perform a few DB insert/update/delete operations and ensure the integrity of the data. Let's take a look at 5 different examples from Laravel open-source projects.


1. themsaid/ergodnc: Create Office with Tags

The code of the Controller:

class OfficeController extends Controller
{
public function create(): JsonResource
{
$attributes = (new OfficeValidator())->validate(
$office = new Office(),
request()->all()
);
 
$attributes['approval_status'] = Office::APPROVAL_PENDING;
$attributes['user_id'] = auth()->id();
 
$office = DB::transaction(function () use ($office, $attributes) {
$office->fill(
Arr::except($attributes, ['tags'])
)->save();
 
if (isset($attributes['tags'])) {
$office->tags()->attach($attributes['tags']);
}
 
return $office;
});
 
// ...
}
}

As you can see, the Office model new record is created, and then, with the many-to-many relation ->attach() method, DB Transaction ensures that if tag attaching fails, then the Office new record is also rolled back.

See the original code on GitHub.


2. JuanDMeGon/Laravel-from-Scratch: Many-To-Many with Deadlocks

The code of the Controller:

class OrderController extends Controller
{
public function store(Request $request)
{
return DB::transaction(function() use($request) {
$user = $request->user();
 
$order = $user->orders()->create([
'status' => 'pending',
]);
 
$cart = $this->cartService->getFromCookie();
 
$cartProductsWithQuantity = $cart
->products
->mapWithKeys(function ($product) {
$quantity = $product->pivot->quantity;
 
if ($product->stock < $quantity) {
throw ValidationException::withMessages([
'cart' => "There is not enough stock for the quantity you required of {$product->title}",
]);
}
 
$product->decrement('stock', $quantity);
$element[$product->id] = ['quantity' => $quantity];
 
return $element;
});
 
$order->products()->attach($cartProductsWithQuantity->toArray());
 
return redirect()->route('orders.payments.create', ['order' => $order->id]);
}, 5);
}
}

Let's discuss what transaction is happening here, and why.

  • We create the Order
  • Then we decrement the stock of $product
  • Finally, we attach Products to the $order

Interesting thing here: did you know you can add a number parameter to the DB::transaction() method?

See above:

DB::transaction(function() use($request) {
// ... whatever is inside
}, 5);

What does that 5 do?

Quote from the original Laravel docs:

The transaction method accepts an optional second argument which defines the number of times a transaction should be retried when a deadlock occurs. Once these attempts have been exhausted, an exception will be thrown.

See the original code on GitHub.


3. amitavroy/doctor-app

The code of the Service class:

class PatientService
{
public function createPatient($patientData): Patient
{
$settingService = app()->make(SettingService::class);
 
try {
DB::beginTransaction();
$patientNumber = $settingService->getNextPatientNumber();
 
$patient = Patient::create([
'patient_id' => now()->format('Ym') . $patientNumber,
'name' => $patientData['name'],
'phone_number' => $patientData['phone_number'],
'year_of_birth' => now()->subYears($patientData['age'])->format('Y'),
'weight' => $patientData['weight'],
]);
 
$settingService->incrementLastPatientNumber();
DB::commit();
 
return $patient;
} catch (Exception $exception) {
logger()->error($exception->getMessage());
}
}
}

This one is interesting: it uses beginTransaction() and commit() manually, and also wraps the transaction in a try .. catch statement, additionally.

See the original code on GitHub.


4. pixelfed/pixelfed: Delete Everything Safely

The code of the Job class:

class DeleteRemoteProfilePipeline implements ShouldQueue
{
// ...
 
public function handle()
{
$profile = $this->profile;
 
DB::transaction(function() use ($profile) {
$profile->avatar->forceDelete();
 
$id = $profile->id;
 
MediaTag::whereProfileId($id)->delete();
StatusHashtag::whereProfileId($id)->delete();
DirectMessage::whereFromId($id)->delete();
FollowRequest::whereFollowingId($id)
->orWhere('follower_id', $id)
->forceDelete();
Follower::whereProfileId($id)
->orWhere('following_id', $id)
->forceDelete();
Like::whereProfileId($id)->forceDelete();
});
}
}

This is pretty straightforward. There are so many things related to the profile, so there's quite a big chance of failure if some of those records malfunction during the deletion process. So DB Transaction is a no-brainer here.

More things are happening in this Job, so see the original code on GitHub.


5. akaunting/akaunting

The code of a custom PHP Action class method:

class Reconciliations extends BulkAction
{
public function reconcile($request)
{
$reconciliations = $this->getSelectedRecords($request);
 
foreach ($reconciliations as $reconciliation) {
\DB::transaction(function () use ($reconciliation) {
$reconciliation->reconciled = 1;
$reconciliation->save();
 
Transaction::where('account_id', $reconciliation->account_id)
->isNotReconciled()
->whereBetween('paid_at', [$reconciliation->started_at, $reconciliation->ended_at])->each(function ($item) {
$item->reconciled = 1;
$item->save();
});
});
}
}
 
}

Reconciliation is a financial term for "merging transactional records" or something like that.

So, we need to mark the reconciliation as saved, but also need to mark individual transactions as reconciled.

Some of you would ask, why there's an ->each() function for each Transaction, instead of just a bulk update? I assume there are Observers or other events that are automatically fired on the individual record update, that would not be automatically executed otherwise.

See the original code on GitHub.


Want More Code Examples?

So, these are just 5 examples. We've collected hundreds of code examples from Laravel open-source projects.

You can take a look at a few more DB transaction examples, or browse through all the list of code examples by topic/tag.

Enjoyed This Tutorial?

Get access to all premium tutorials, video and text courses, and exclusive Laravel resources. Join our community of 10,000+ developers.

Comments & Discussion

LN
Loganathan Natarajan ✓ Link copied!

Thanks for sharing and learned new things.

BK
Brown Ken ✓ Link copied!

Informative

S
seskie ✓ Link copied!

thanks for sharing

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.