---
title: "Rezervácie — Credits for Laravel | Roundly"
description: "Rezervujte kredity teraz, neskôr ich strhnite celé či čiastočne, uvoľnite alebo nechajte expirovať — pod tým istým zámkom ako každý odpis."
url: https://roundly-consulting.com/sk/open-source/navody/credits-for-laravel/rezervacie
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)

# Rezervácie

Rezervácia (hold) vyhradí kredity v skupine bez zápisu do knihy pohybov. Znižuje to, čo sa dá minúť, kým ju strhnete — celú, alebo čiastočne so zvyškom uvoľneným —, uvoľníte, alebo kým neexpiruje. Typicky ide o pokladňu, ktorá kredity rezervuje počas platby, alebo o volanie API, ktoré si vopred rezervuje odhadovanú cenu.

## Zapnutie rezervácií

Rezervácie potrebujú tabuľku credit\_holds (pozrite Inštalácia) a sú vypnuté, kým ich nezapnete — dovtedy ochrana pri odpise tabuľku rezervácií nikdy nečíta:

```bash
CREDITS_HOLDS=on
# optional: holds created without their own expiry live this long
CREDITS_HOLD_EXPIRE_AFTER_MINUTES=30
```

## Rezervácia, strhnutie, uvoľnenie

```php
use RoundlyConsulting\Credits\Facades\Credits;

$hold = Credits::for($user)->hold(30, now()->addMinutes(15), 'Order #42', ['order' => 42]);

Credits::for($user)->balance();    // 100 — the ledger is untouched
Credits::for($user)->held();       // 30
Credits::for($user)->available();  // 70 — what a debit or another hold can still take

$hold->capture();        // debit all 30 (one ledger row), or…
$hold->capture(12);      // …debit 12 and release the other 18, or…
$hold->release();        // …free all of it, nothing written to the ledger
```

Ploché metódy fasády prijímajú CreditHoldData a samotnú rezerváciu; capture() a release() na scope rezerváciu iného vlastníka odmietnu:

```php
use RoundlyConsulting\Credits\DataTransferObjects\CreditHoldData;
use RoundlyConsulting\Credits\Facades\Credits;

$hold = Credits::hold($user, new CreditHoldData(amount: 30, expiresAt: now()->addMinutes(15), bucket: 'points'));

Credits::capture($hold, 20, 'Order #42');        // the debit row (-20); the other 10 are released
Credits::release($hold);                         // throws CreditHoldNotActiveException — already captured

Credits::for($user)->bucket('points')->release($otherHold); // ForeignCreditHoldException for another owner's hold
Credits::held($user, 'points');                  // int
Credits::available($user, 'points');             // int
Credits::for($user)->hasAvailable(50);           // bool
```

Skratky v traite (nie sú súčasťou rozhrania Creditable):

```php
$hold = $user->holdCredits(30, now()->addMinutes(15), bucket: 'points');

$user->heldCredits('points');           // 30
$user->availableCredits('points');      // balance minus active holds
$user->hasAvailableCredits(50, 'points');
```

$amount musí byť kladné a $expiresAt v budúcnosti (InvalidArgumentException); suma strhnutia musí byť 1..$hold->amount a popis aj meta sa predvolene preberú z rezervácie. $hold->capture() a $hold->release() idú cez manažéra, takže ich fake zaznamená, a odovzdaná rezervácia sa aktualizuje na mieste (status, captured\_amount, credit\_id, resolved\_at).

## Pravidlá

- Dostupné = zostatok − aktívne rezervácie, pre každú skupinu. Aktívna rezervácia je v stave held a jej expires\_at ešte neuplynulo. balance(), has() aj balance v CreditsModified zostávajú zostatkom knihy pohybov.
- Rezervácia sa stráži ako odpis: pokiaľ nie je povolené prečerpanie (na scope alebo cez credits.allow\_overdraft), nesmie dostať dostupný zostatok pod credits.minimum\_balance — InsufficientCreditsException, ktorej $available je dostupný zostatok.
- Odpisy rešpektujú rezervácie: pri zapnutých rezerváciách rozhoduje strážený odpis podľa dostupného zostatku. Odpis s povoleným prečerpaním môže rezervované kredity minúť aj tak.
- Strhnutie sa kvôli minimálnemu zostatku nikdy neodmietne — rezervácia kredity už vyhradila. Zapíše jeden odpis do knihy pohybov, na ktorý odkazuje credit\_id rezervácie.
- Každá rezervácia sa vyrieši raz: strhnutie či uvoľnenie rezervácie, ktorá už bola strhnutá, uvoľnená, expirovala (upratovaním alebo len uplynutím expires\_at) alebo bola zmazaná, vyhodí CreditHoldNotActiveException so stavom, v ktorom ju našlo.
- Expirácia platí okamžite, upratovanie je len evidencia: rezervácia prestane kredity vyhradzovať v momente, keď uplynie expires\_at; upratovanie ju označí ako expired a spustí CreditHoldExpired.
- Rezervácie žijú na spojení knihy pohybov — spojení modelu credits.model, inak vlastníka — vedľa záznamov knihy pohybov a zámku vlastníka.

## Odolnosť voči súbehu

Každá rezervácia, strhnutie, uvoľnenie aj expirácia vezme zámok vlastníka (ten istý riadok credit\_locks, ktorý zvyšuje odpis) a všetko, podľa čoho rozhoduje, znova načíta pod zámkami riadkov, v jednej transakcii so svojím zápisom:

| Súbeh | Výsledok |
| --- | --- |
| Dve rezervácie, ktoré spolu prekročia dostupný zostatok | druhá počká a potom sa odmietne (InsufficientCreditsException) |
| Rezervácia a odpis tých istých kreditov | odmietne sa tá operácia, ktorá sa potvrdí ako druhá |
| Dve strhnutia jednej rezervácie | jeden odpis; druhé dostane CreditHoldNotActiveException (captured) |
| Strhnutie a upratovanie expirovaných rezervácií | vyhrá strhnutie (upratovanie ho preskočí) alebo upratovanie (strhnutie dostane expired) — nikdy oboje |
| Strhnutie a uvoľnenie | jedno vyhrá; druhé dostane CreditHoldNotActiveException |

Na Postgres pri REPEATABLE READ / SERIALIZABLE čakajúca transakcia zlyhá so SQLSTATE 40001 a zopakuje sa s novým snapshotom, presne ako pri odpisoch.

## Upratovanie expirovaných rezervácií

Naplánujte upratovanie — príkaz alebo job do fronty:

```php
// routes/console.php
use Illuminate\Support\Facades\Schedule;
use RoundlyConsulting\Credits\Jobs\ExpireCreditHolds;

Schedule::command('credits:expire-holds')->everyMinute()->withoutOverlapping();
// or queued:
Schedule::job(new ExpireCreditHolds)->everyMinute();
```

- credits:expire-holds {--connection=} vypíše, koľko rezervácií expiroval; pri vypnutých rezerváciách to oznámi a skončí úspešne.
- Credits::expireHolds(?$now, ?$connection) je to isté upratovanie a vráti počet; $now uprace stav k danému okamihu. Rezervácie číta po 100 na spojení modelu knihy pohybov, inak na predvolenom — ak žijú inde, zadajte $connection.
- Bezpečné aj na viacerých serveroch naraz: každá rezervácia expiruje najviac raz, pod zámkom svojho vlastníka. Expiruje aj rezervácia, ktorej vlastník bol zmazaný.

## Tabuľka credit\_holds

| Stĺpec | Typ | Poznámka |
| --- | --- | --- |
| `id` | per primary\_key\_type | |
| `creditable_type / creditable_id` | morph pair, id per key\_type | Indexované. |
| `bucket` | string | |
| `amount` | bigInteger | Rezervovaná suma. |
| `status` | string(16) | held, captured, released alebo expired. |
| `captured_amount` | bigInteger, nullable | |
| `credit_id` | per primary\_key\_type, nullable | Záznam strhnutia v knihe pohybov. |
| `description / meta` | string / json, nullable | |
| `expires_at / resolved_at` | timestamp, nullable | Uložené v app.timezone, porovnávané ako presné okamihy. |
| `created_at / updated_at / deleted_at` | timestamps, soft deletes | Zmazaná rezervácia sa už nezapočítava. |

Indexy: (creditable\_type, creditable\_id, bucket, status) a (status, expires\_at). CreditHold má factory na priame vytvorenie rezervácií.

## 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)
