---
title: Dve relácie, jeden identifikátor
type: anti-pattern
level: L2
status: live
revision: 1
updated: 2026-08-14
systemVersion: 4.2
authoring: machine-translated
tags: [data-integrity, concurrency, identifiers]
rating: 8.35
ratingAxes: useful 8 · evidence 9 · pull 8 · original 8 · form 9
ratingKind: derived
source: controlling ledger duplicate IDs, 2026-08-14
---

# Dve relácie, jeden identifikátor

_Written 2026-08-14 · last verified 2026-08-14 · system v4.2 · live_

**TL;DR** — Dve súbežné relácie zapísali záznamy pod tým istým identifikátorom v priebehu niekoľkých minút. Obe si vzali ďalšie číslo zo súhrnného riadku na začiatku súboru namiesto z najvyššieho čísla, ktoré sa v ňom skutočne nachádzalo. Prideľovanie identifikátora z uloženého (cachovaného) počtu namiesto z aktuálneho maxima sa rozbije vo chvíli, keď čokoľvek beží paralelne.

## Vzor

Záznamy v evidencii sú číslované postupne. Ak chcete pridať nový, prečítate hlavičku — *najvyššie ID: 51* — a zapíšete 52.

Dva behy to urobia s odstupom niekoľkých minút. Obidva zapíšu 52. Jedna evidencia tak nakoniec obsahovala 34 blokov záznamov pod 33 unikátnymi identifikátormi. Jeden identifikátor teraz ukazuje na dve rôzne zistenia a každý odkaz naň je nejednoznačný.

## Prečo to vyzerá správne

Hlavička existuje presne preto, aby nikto nemusel prehľadávať celý súbor. Jej čítanie je rýchlejšie a v okamihu zápisu bola správna.

Pri jednovláknovom behu to funguje roky. Chyba je neviditeľná, kým niečo nebeží dvakrát naraz — a dovtedy sa tento postup stihne zaužívať všade.

## Prečo to zlyháva

Hlavička je **cache faktu, ktorý žije v tele súboru**. Každé čítanie z cache bez zámku na zápis je pretekom (race condition) a jeho okno je rovnako dlhé ako medzera medzi čítaním a zápisom — čo je pri procese riadenom človekom skôr minúty než milisekundy.

Náprava je tá nákladná časť. Prečíslovanie čerstvého duplikátu je mechanická záležitosť. Prečíslovanie starého záznamu znamená nájsť každý krížový odkaz v každom inom súbore, ktorý dané číslo cituje — a ak sa čo i len jeden odkaz prehliadne, ticho ukazuje na nesprávny záznam.

## Namiesto toho

**Prideľujte z aktuálneho maxima, nie zo súhrnu.** Tesne pred zápisom vyhľadajte (grep) v tele súboru najvyšší identifikátor:

> `grep -o '^### CTRL-[0-9]*' ledger.md | sort | tail -1`

Oplatia sa ešte dve ďalšie pravidlá. Robte identifikátory lacno unikátnymi — časová pečiatka alebo krátka náhodná prípona pretek úplne odstráni, za cenu menej elegantného výsledku. A keď duplikát nájdete, **opravte ten mladší a starý iba označte**: mladý záznam ešte nemá žiadne prichádzajúce odkazy, starý ich môže mať mnoho, a mechanické prečíslovanie starého mení viditeľnú kolíziu na súbor tichých zavádzajúcich odkazov.
