---
title: "Ochrana pred prečerpaním — Credits for Laravel | Roundly"
description: "Odpis pod hranicu predvolene vyhodí InsufficientCreditsException; prečerpanie povolíte pre jedno volanie alebo globálne, bezpečne aj pri súbehu."
url: https://roundly-consulting.com/sk/open-source/navody/credits-for-laravel/ochrana-pred-precerpanim
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Credits for Laravel](https://roundly-consulting.com/sk/open-source/navody/credits-for-laravel.md)

# Ochrana pred prečerpaním

Odpis, ktorý by zostatok dostal pod minimum\_balance (predvolene nula), sa predvolene odmietne výnimkou InsufficientCreditsException — zostatok nemôže potichu klesnúť do mínusu a nič sa nezapíše. Na fasáde vráti allowOverdraft() scope, ktorý smie klesnúť pod hranicu:

```php
use RoundlyConsulting\Credits\Exceptions\InsufficientCreditsException;

try {
    Credits::for($user)->deduct(1000, 'big purchase');
} catch (InsufficientCreditsException $e) {
    // $e->requested, $e->available, $e->minimum, $e->creditable — nothing was written
}

Credits::for($user)->allowOverdraft()->deduct(1000, 'manual debit');   // may go below the floor
Credits::for($user)->allowOverdraft()->setTo(-50, 'write-off');
```

To isté cez trait:

```php
use RoundlyConsulting\Credits\Exceptions\InsufficientCreditsException;

try {
    $user->modifyCredits(-1000, 'big purchase');
} catch (InsufficientCreditsException $e) {
    $e->requested;    // -1000 — the signed amount that was refused
    $e->available;    // 70 — the bucket's balance when the guard decided
    $e->minimum;      // 0 — the floor the guard enforced (credits.minimum_balance)
    $e->creditable;   // the entity
    $e->getMessage(); // 'Insufficient credits: tried to deduct 1000 but only 70 are available.'
}
```

## Povolenie prečerpania

Záporný zostatok povolíte pre jedno volanie — cez allowOverdraft() na scope alebo argument allowOverdraft pri metódach traitu:

```php
$user->modifyCredits(-1000, 'manual debit', allowOverdraft: true);

$user->setCreditsTo(-50, 'write-off', allowOverdraft: true);
```

Alebo globálne, konfiguračným kľúčom allow\_overdraft či jeho env premennou. Hodnota z env sa číta ako boolean: 1, true, on a yes ho zapnú; 0, false, off a no ho nechajú vypnuté; čokoľvek iné vyhodí InvalidConfigurationException s názvom kľúča:

```bash
CREDITS_ALLOW_OVERDRAFT=true   # 1, true, on or yes — 0, false, off or no leave it off; anything else throws
```

## Vlastná hranica

minimum\_balance je hranica, ktorú ochrana stráži. Zvýšte ju, ak chcete držať rezervu, alebo ju nastavte pod nulu pre ohraničené prečerpanie:

```php
// config/credits.php — a bounded overdraft: balances may fall to -500, never below
'minimum_balance' => -500,
```

Pri nenulovej hranici výnimka uvedie, koľko sa nad ňou ešte dá minúť, a $e->minimum nesie samotnú hranicu — pri minimum\_balance 50 a jazyku aplikácie sk znie odmietnutý odpis 60 zo zostatku 100: „Nedostatočný zostatok kreditov: pokus o odpočítanie 60, nad minimálnym zostatkom 50 je však možné minúť iba 50.“

Ochrana platí pre každú skupinu zvlášť: odpis zo skupiny purchased nikdy nesiahne na promo kredity. Pripísania ochranou vôbec neprechádzajú.

## Súbežnosť

Zostatok nikdy nie je uložený stĺpec — je to súčet knihy pohybov, ktorá sa len dopĺňa. Každá zmena (add, deduct, modify, setTo a ich podoby pre Money) beží v jednej transakcii, ktorá najprv vezme zámok vlastníka — UPDATE jeho riadku v credit\_locks — potom načíta záznamy skupiny pod lockForUpdate(), rozhodne (ochrana pred prečerpaním pri odpise, rozdiel pri setTo()) a pridá nový záznam. Súbežné zmeny toho istého vlastníka sa preto zoradia za sebou na každej úrovni izolácie:

- READ COMMITTED (predvolená v Postgres): druhá zmena počká na prvú a potom načíta zostatok, ktorý po sebe prvá nechala — aj v prázdnej skupine so zápornou minimum\_balance.
- MySQL / MariaDB pri REPEATABLE READ (ich predvolená úroveň): zámok aj čítanie knihy pohybov sú aktuálne čítania, takže vidia aj potvrdený záznam prvej zmeny.
- Postgres pri REPEATABLE READ / SERIALIZABLE: snímka druhej zmeny je staršia než jej čakanie, preto namiesto rozhodovania nad zastaranými dátami zlyhá na chybe serializácie (SQLSTATE 40001) a balík jej transakciu zopakuje — najviac 5 pokusov — s novou snímkou.

## Vo vašej vlastnej transakcii

Vo vašej vlastnej DB::transaction() patrí snímka vašej transakcii, takže balík ju za vás zopakovať nemôže: na Postgres pri REPEATABLE READ / SERIALIZABLE sa súbežná zmena prejaví ako Illuminate\\Database\\DeadlockException (SQLSTATE 40001) a nič sa nezapíše. Zopakujte celú transakciu — DB::transaction($callback, attempts: 3) to neurobí, pretože vnorená výnimka už nenesie SQLSTATE, podľa ktorého Laravel rozhoduje o opakovaní:

```php
use Illuminate\Database\DeadlockException;
use Illuminate\Support\Facades\DB;
use RoundlyConsulting\Credits\Facades\Credits;

retry(3, fn () => DB::transaction(function () use ($user): void {
    // … your own reads and writes …
    Credits::for($user)->deduct(30, 'purchase');
}), when: fn (Throwable $e): bool => $e instanceof DeadlockException);
```

Zámok sa drží len počas tejto krátkej transakcie. Keďže každá zmena sa zapíše ako nový rozdielový záznam (nikdy nie absolútny zostatok), žiadna zmena sa nestratí a credit\_locks drží len počítadlo verzií — jediným zdrojom pravdy ostáva kniha pohybov.

## Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

[Ďalšie spôsoby podpory vrátane kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/credits-for-laravel.md)
