Site

Transações e Locks

v4

Use \DB::transaction() para operações atômicas elock_for_update() para evitar race conditions.


Transação

use MUCRM\engine\date_time\time;

\DB::transaction(function () use ($customer_id, $price, $plan_id) {
    $customer = customer::with('wallet')->find($customer_id);

    if ($customer->wallet->balance < $price) {
        throw new \Exception('Saldo insuficiente.');
    }

    $customer->wallet->balance -= $price;
    $customer->wallet->save();

    $customer->subscription()->update([
        'plan_id'    => $plan_id,
        'status'     => 'active',
        'expires_at' => time::now()->add_days(30)->to_sql(),
    ]);
});

lock_for_update()

Sempre dentro de uma transação:

\DB::transaction(function () {
    $customer = customer::where('id', 1)
        ->lock_for_update()
        ->first();

    $customer->credits -= 100;
    $customer->save();
});
\DB::transaction(function () use ($product_id) {
    $product = shop_item::where('id', $product_id)
        ->lock_for_update()
        ->first();

    if ($product->stock <= 0) {
        throw new \Exception('Produto sem estoque.');
    }

    $product->stock -= 1;
    $product->save();
});