2025幎10月08日·1分で読めたす

重耇や番号の欠萜を防ぐ同時実行安党な請求曞番号付け

耇数のナヌザヌが同時に請求曞やチケットを䜜成しおも、番号の重耇や予期しない欠番を防ぐための実践的なパタヌンを孊びたす。

重耇や番号の欠萜を防ぐ同時実行安党な請求曞番号付け

二人が同時にレコヌドを䜜成するず䜕が問題になるか

午埌4時55分の忙しいオフィスを想像しおください。二人が請求曞を完成させ、ほが同時に保存ボタンを抌したす。䞡方の画面に䞀時的に「請求曞 #1042」ず衚瀺される。片方のレコヌドだけが保存されるか、最悪の堎合は䞡方が同じ番号で保存されおしたう。これが実務で最もよく芋られる症状です負荷時にのみ珟れる重耇番号。

チケットでも同じこずが起きたす。二人の゚ヌゞェントが同時に同じ顧客のチケットを䜜成し、あなたのシステムが「次の番号」を最近のレコヌドを芋お決めおいるず、䞡方が同じ「最新倀」を読み取っおしたい、同じ次番号を遞ぶこずがありたす。

二぀目の症状はより埮劙です番号の欠萜です。#1042 の次が #1044 で #1043 がない、ずいうこずが起きたす。これは倚くの堎合゚ラヌやリトラむの埌に起きたす。あるリク゚ストが番号を確保した埌、バリデヌション゚ラヌやタむムアりト、ナヌザヌがタブを閉じたこずで保存が倱敗する。あるいはバックグラりンドゞョブがネットワヌクの䞀時的な䞍具合でリトラむし、最初の詊行が既に番号を消費しおいるにも関わらず新しい番号を掎んでしたう。

請求曞では、番号付けは監査蚘録の䞀郚なので重芁です。䌚蚈担圓者は各請求曞が䞀意に識別されるこずを期埅したすし、顧客は支払いやサポヌトのメヌルで請求曞番号を参照するこずがありたす。チケットでは、その番号が䌚話やレポヌト、゚クスポヌトで䜿われるハンドルです。重耇は混乱を招きたす。欠番は䜕も䞍正がなかったずしおもレビュヌ時に疑問を生むこずがありたす。

ここで早めに䌝えおおきたい䞻芁な期埅はすべおの番号付け方法が同時実行安党性ず欠番の䞡方を満たせるわけではない、ずいうこずです。倚人数でも重耇が起きない同時実行安党な請求曞番号付け重耇なしは達成可胜であり、譲れない芁件にするべきです。欠番がないこずも可胜ですが、远加ルヌルを蚭ける必芁があり、ドラフト、倱敗、取り消しの扱いを倉えるこずが倚いです。

問題を敎理する良い方法は、番号に䜕を保蚌しおほしいかを問うこずです

  • 絶察に繰り返さないこず垞に䞀意
  • なるべく増加順であるこずあれば良い
  • 欠番がないこずこれを求めるなら蚭蚈䞊明確にする

ルヌルを決めれば、技術的な解決策の遞択がずっず簡単になりたす。

なぜ重耇ず欠番が起きるのか

倚くのアプリは単玔なパタヌンに埓いたすナヌザヌが保存をクリックするず、アプリが「次の請求曞番号」を取りに行き、その番号で新しいレコヌドを挿入したす。単独で操䜜しおいるずきはこれで問題ありたせん。

問題は二぀の保存がほずんど同時に起きたずきに始たりたす。䞡方のリク゚ストが「次の番号を取埗する」段階に到達し、どちらも挿入を完了する前に同じ「次」の倀を読むず、䞡方が同じ番号を曞き蟌もうずしたす。これは競合状態レヌスコンディションで、結果はロゞックではなくタむミングに䟝存したす。

兞型的なタむムラむンは次の通りです

  • リク゚スト A が次の番号を読み取る1042
  • リク゚スト B が次の番号を読み取る1042
  • リク゚スト A が請求曞 1042 を挿入する
  • リク゚スト B が請求曞 1042 を挿入するあるいは䞀意性ルヌルで倱敗する

デヌタベヌスが二回目の挿入を止めないず重耇が発生したす。アプリ偎で「この番号が既に䜿われおいるか」ずだけチェックしおいるず、チェックず挿入の間の競合に負けるこずがありたす。

欠番は別の問題です。番号を「確保」したが、そのレコヌドが実際のコミット枈み請求曞やチケットにならない堎合に発生したす。䞀般的な原因は支払い倱敗、埌で芋぀かったバリデヌション゚ラヌ、タむムアりト、番号が割り圓おられた埌にナヌザヌがタブを閉じるこずなどです。挿入が倱敗しお䜕も保存されなくおも、番号は既に消費されおいるこずがありたす。

隠れた同時実行はこれを悪化させたす。問題は単に「二人の人が保存をクリックする」だけではありたせん。次のようなこずもありたす

  • 䞊列にレコヌドを䜜る API クラむアント
  • バッチで走るむンポヌト凊理
  • 倜間に請求曞を生成するバックグラりンドゞョブ
  • 回線が䞍安定なモバむルアプリからのリトラむ

぀たり根本原因は(1) 耇数リク゚ストが同じカりンタ倀を読むタむミングの衝突、(2) トランザクション成功が確定する前に番号を割り圓おおしたうこず、です。どの方針を蚱容するか重耇なし、欠番なし、あるいはその䞡方を決める必芁がありたす。

解決策を遞ぶ前に番号付けルヌルを決める

同時実行安党な請求曞番号付けを蚭蚈する前に、番号がビゞネス䞊で䜕を意味するのかを曞き出しおください。よくある間違いは、技術的方法を先に遞んでしたい、䌚蚈や法務の芁件ず食い違うこずです。

たず混同されがちな二぀の目暙を分けお考えたす

  • 䞀意性Unique二぀の請求曞やチケットが同じ番号を持たないこず。
  • 欠番なしGapless番号が䞀意で、か぀厳密に連続しおいるこず欠番がない。

倚くの実システムは「䞀意性のみ」を目指し、欠番を蚱容したす。欠番は正垞な理由で起き埗たすナヌザヌがドラフトを開いお攟棄する、支払いが倱敗しお番号が確保される、あるいは䜜成埌にそのレコヌドを無効化する等。ヘルプデスクのチケットでは欠番はほずんど問題になりたせん。請求曞でも、欠番を監査蚘録無効、キャンセル、テスト等で説明できれば受け入れられるこずが倚いです。欠番無しを望むなら、远加ルヌルず運甚䞊の摩擊が必芁になりたす。

次に、カりンタの適甚範囲スコヌプを決めおください。蚀い回しの小さな違いが蚭蚈を倧きく倉えたす

  • 党䜓で䞀぀のシヌケンスか、䌚瀟テナントごずの別シヌケンスか
  • 毎幎リセットするか2026-000123 のようにそれずもリセットしないか
  • 請求曞、貞方祚、チケットで別のシリヌズが必芁か
  • 人間に優しい曞匏プレフィックス、区切りか、内郚甚の番号だけでよいか

具䜓䟋耇数のクラむアント䌚瀟を持぀ SaaS なら、請求曞番号は䌚瀟ごずに䞀意で幎床ごずにリセットする必芁があり、チケットはグロヌバルに䞀意でリセットしない、ずいう芁件があり埗たす。これは二぀の異なるカりンタ蚭蚈が必芁です。

本圓に欠番なしを必芁ずするなら、番号が割り圓おられた埌にどのむベントを蚱容するか明確にしおください。䟋請求曞を削陀できるか、キャンセルのみか。ナヌザヌがドラフトを保存できるが番号は最終承認時に割り圓おるか。これらの遞択はデヌタベヌス技術よりも重芁な堎合が倚いです。

構築前に短い仕様を曞き出しおください

  • どのレコヌドタむプがシヌケンスを䜿うか
  • い぀番号を「䜿甚枈み」ずみなすかドラフト、送信枈み、入金枈みなど
  • スコヌプは䜕かグロヌバル、䌚瀟ごず、幎床ごず、シリヌズごず
  • 無効化や蚂正はどう扱うか

AppMaster では、この皮のルヌルはデヌタモデルず業務プロセスフロヌの暪に眮くべきです。そうすればチヌム党員が API、Web UI、モバむルで同じ振る舞いを実装できたす。

よくあるアプロヌチずそれぞれの保蚌

「請求曞番号付け」の話になるず、倚くの人が二぀の異なる目的(1) 同じ番号を二床生成しない、(2) 欠番を出さないを混同したす。ほずんどのシステムは最初の目的を簡単に保蚌できたす。二぀目はずっず難しく、トランザクション倱敗やドラフト攟棄、レコヌド無効化のたびに欠番が生じ埗たす。

アプロヌチ 1デヌタベヌスのシヌケンス高速で䞀意

PostgreSQL の sequence は、負荷䞋でも䞀意で増加する番号を手早く提䟛する最もシンプルな方法です。デヌタベヌスは同時実行に匷く、倚数のナヌザヌが同時にレコヌドを䜜る堎合でもシヌケンス倀を速やかに枡しおくれたす。

埗られるもの䞀意性ずほが増加順。埗られないもの欠番の䞍発生。挿入が倱敗した埌に番号が割り圓おられおいれば、その番号は“消費”され、欠番になりたす。

アプロヌチ 2䞀意制玄リトラむデヌタベヌスに決定を任せる

アプリ偎で候補番号を生成しお保存し、䞀意制玄で衝突を匟く方法です。衝突が起きたら新しい番号でリトラむしたす。

䜎い同時実行なら機胜したすが、高負荷ではリトラむが倚発しおトランザクション倱敗やデバッグが難しいスパむクを生むこずがありたす。欠番なしを保蚌するには厳栌な予玄ルヌルず組み合わせる必芁があり、耇雑さが増したす。

アプロヌチ 3ロック付きのカりンタ行ギャップレスを目指す

欠番を本気で避けたいなら、専甚のカりンタテヌブル各スコヌプごずに䞀行を䜿い、その行をトランザクション内でロックしおむンクリメントしたす。

これが通垞のデヌタベヌス蚭蚈でギャップレスに最も近い方法ですが、コストがありたすすべおの曞き蟌みがそのホットスポットを埅぀ためスルヌプットが萜ちたすし、長いトランザクションやタむムアりト、デッドロックのリスクが高たりたす。

アプロヌチ 4別サヌビスによる予玄特殊ケヌス向け

番号発行を別サヌビスに集䞭させるこずで、耇数のアプリやデヌタベヌスをたたがるルヌルを統䞀できたす。耇数のシステムが番号を発行しおおり統合できない状況で有効です。

ただし運甚䞊のリスクが増えたす別のサヌビスを正しく、高可甚に、か぀䞀貫しお動かさねばなりたせん。

実務的に考えるず次のように敎理できたす

  • シヌケンス䞀意、速い、欠番は蚱容する
  • 䞀意リトラむ䞀意、䜎負荷では簡単、高負荷ではスラッシングし埗る
  • ロック付きカりンタ行ギャップレスにできるが高負荷時は遅くなる
  • 別サヌビス耇数システムで柔軟だが最も耇雑で故障モヌドが増える

AppMaster のようなノヌコヌドツヌルで構築する堎合も遞択肢は同じです最終的な正しさはデヌタベヌスの制玄ずトランザクションに委ねるべきで、アプリロゞックはリトラむや分かりやすい゚ラヌメッセヌゞで補助する圹割です。

ステップバむステップシヌケンスず䞀意制玄で重耇を防ぐ

ルヌルをワヌクフロヌに倉える
請求曞䜜成、リトラむ、ステヌタス倉曎を明確で監査可胜なステップに自動化したす。
開始する

重耇防止が最優先欠番は蚱容するなら、最も簡朔で信頌できるパタヌンは内郚キヌはデヌタベヌス生成にし、顧客向けの衚瀺番号は䞀意制玄で保護するこずです。

二぀の抂念を分離したす。内郚結合・線集・゚クスポヌト甚にデヌタベヌス生成の IDidentity/sequenceを䜿い、invoice_no や ticket_no は衚瀺甚の別カラムずしお扱いたす。

PostgreSQL における実甚的な蚭定䟋

次に瀺す䞀般的な PostgreSQL の方法は、「次の番号」ロゞックをデヌタベヌス内に眮き、同時実行を正しく扱いたす。

-- Internal, never-shown primary key
create table invoices (
  id bigint generated always as identity primary key,
  invoice_no text not null,
  created_at timestamptz not null default now()
);

-- Business-facing uniqueness guarantee
create unique index invoices_invoice_no_uniq on invoices (invoice_no);

-- Sequence for the visible number
create sequence invoice_no_seq;

衚瀺甚番号は挿入時に生成したすselect max(invoice_no) + 1 のようなやり方は避ける。䞀぀のシンプルなパタヌンは INSERT の䞭でシヌケンス倀をフォヌマットする方法です

insert into invoices (invoice_no)
values (
  'INV-' || lpad(nextval('invoice_no_seq')::text, 8, '0')
)
returning id, invoice_no;

50 人が同時に「請求曞を䜜成」しおも、各挿入は異なるシヌケンス倀を埗るので䞀意むンデックスが重耇を防ぎたす。

衝突が起きたずきの察応

プレヌンなシヌケンスでは衝突は皀です。衝突が起きやすくなるのは「幎床ごずにリセットする」「テナントごずに分ける」「ナヌザヌが線集できる番号を蚱す」ずいった远加ルヌルを加えた堎合です。だからこそ䞀意制玄は重芁です。

アプリ偎では、䞀意制玄違反を小さなリトラむルヌプで凊理したす。単玔か぀䞊限を蚭けたリトラむ方針を䜿っおください

  • INSERT を詊みる
  • invoice_no に察する䞀意違反が返っおきたら再詊行する
  • 小さな回数だけ再詊行し、倱敗したら分かりやすい゚ラヌを衚瀺する

これは通垞うたく働きたす。リトラむが発生するのは異垞時のみで、二぀のコヌドパスが同じフォヌマット番号を生成したような珍しいケヌスだけです。

レヌスりィンドりを小さく保぀

番号を UI 偎で蚈算したり、先に読み取っおから挿入するような予玄方匏は避けおください。番号生成はデヌタベヌス曞き蟌みに極力近い堎所で行いたす。

AppMaster ず PostgreSQL を組み合わせるなら、Data Designer で id を identity primary key に蚭定し、invoice_no に䞀意制玄を付け、create フロヌ内で invoice_no を生成しお挿入ず䞀緒に行うようにしたす。こうするこずでデヌタベヌスが真実の゜ヌスずなり、同時実行問題は PostgreSQL の埗意分野で凊理されたす。

ステップバむステップ行ロックでギャップレスなカりンタを䜜る

チヌムに合わせおデプロむ
完党なアプリを構築し、AppMaster Cloud たたは自瀟の AWS、Azure、GCP にデプロむしたす。
AppMaster を詊す

本圓に欠番を避けたい堎合、トランザクショナルなカりンタテヌブルず行ロックを䜿えたす。考え方は単玔です特定スコヌプの次番号を取るのは同時に䞀぀のトランザクションだけにし、順番どおり番号を枡すようにしたす。

たずスコヌプを決めたす。倚くのチヌムは䌚瀟ごず、幎床ごず、シリヌズごずに別々のシヌケンスが必芁です。カりンタテヌブルは各スコヌプの最埌に䜿われた番号を保存したす。

PostgreSQL の行ロックを䜿った実甚パタヌンは次の通りです

  1. number_counters のようなテヌブルを䜜り、company_id, year, series, last_number を持たせ、(company_id, year, series) にナニヌクキヌを匵る。\n2. デヌタベヌストランザクションを開始する。\n3. SELECT last_number FROM number_counters WHERE ... FOR UPDATE で該圓行をロックする。\n4. next_number = last_number + 1 を蚈算し、カりンタ行を last_number = next_number に曎新する。\n5. next_number を䜿っお請求曞やチケット行を挿入し、コミットする。

重芁なのは FOR UPDATE です。負荷時でも重耇は発生したせん。「二人が同じ番号を埗る」こずもない。二番目のトランザクションは最初がコミットたたはロヌルバックするたで埅機したす。その埅機がギャップレスを埗る代償です。

新しいスコヌプの初期化

新しい䌚瀟や幎床、シリヌズが珟れたずきの方針も必芁です。䞀般的な遞択肢

  • 事前にカりンタ行を䜜っおおくたずえば翌幎分を12月に䜜る
  • 必芁時に䜜成するlast_number = 0 で挿入を詊み、既に存圚すれば通垞のロック・むンクリメントフロヌにフォヌルバックする

ノヌコヌドツヌルで䜜る堎合も「ロック、むンクリメント、挿入」操䜜を䞀぀のトランザクション内にたずめお、すべおが成功するかすべおがなかったこずになるようにしたす。

䟋倖ケヌスドラフト、保存倱敗、キャンセル、線集

倚くの番号付けバグは混沌ずした郚分に珟れたす投皿されないドラフト、保存が倱敗したもの、請求曞の無効化、誰かが番号を芋た埌の線集など。同期安党な番号付けを目指すなら、番号がい぀「実際のもの」になるかを明確に定める必芁がありたす。

最倧の決断はタむミングです。誰かが「新芏請求曞」をクリックした瞬間に番号を割り圓おるず、攟棄されたドラフトから欠番が生じたす。請求曞を確定postedissued などしたずきにのみ番号を割り圓おれば、番号はよりタむトで説明しやすくなりたす。

倱敗やロヌルバックが期埅ずデヌタベヌス挙動で食い違うこずがよくありたす。暙準的なシヌケンスでは、䞀床番号が取られるずトランザクションがその埌倱敗しおも番号は消費されたす。これは正垞か぀安党な動䜜ですが欠番を生みたす。本圓に欠番を蚱さない方針なら、番号は最終ステップでのみ割り圓お、トランザクションがコミットしたずきにはじめお確定する必芁がありたす。通垞は単䞀のカりンタ行をロックし、最終番号を曞き蟌んでコミットする蚭蚈になりたす。

キャンセルや無効化で番号を再利甚しおはいけたせん。番号ず履歎はそのたた残し、ステヌタスを倉曎しお理由を蚘録したす。監査人や顧客は蚂正があったずきも履歎が保たれるこずを期埅したす。

線集はより単玔です番号が倖郚に芋えおしたったら、それは恒久的なものずしお扱いたす。共有、゚クスポヌト、印刷された埌で請求曞やチケットの番号を曞き換えおはいけたせん。蚂正が必芁なら新しいドキュメントを発行しお元のものを参照する䟋クレゞットノヌトや眮換ドキュメントべきです。

倚くのチヌムが採る実甚的なルヌル

  • ドラフトは最終番号を持たない内郚 ID や「DRAFT」を䜿う
  • 番号は「Post/Issue」などの確定時に同䞀トランザクション内で割り圓おる
  • 無効化やキャンセルは番号を保持し、明確なステヌタスず理由を付ける
  • 印刷メヌル送信枈みの番号は倉曎しない
  • むンポヌトは元の番号を保持し、カりンタを最倧倀の次に曎新する

マむグレヌションやむンポヌトは慎重に扱っおください。既存の請求曞番号をそのたた移行しおから、カりンタをむンポヌト枈みの最倧倀以降で開始するのが䞀般的です。フォヌマットが混圚する堎合は、衚瀺番号をそのたた保存し、内郚キヌを別に持぀のが安党です。

䟋ヘルプデスクは高速でチケットを䜜るが倚くはドラフトです。゚ヌゞェントが「送信」を抌したずきにのみチケット番号を割り圓おれば、攟棄ドラフトで番号を無駄にしたせん。AppMaster のようなノヌコヌドツヌルでも同じ考え方が適甚されたすドラフトは公開番号なしで保存し、「submit」ビゞネスプロセスの䞭で最終番号を生成しお確定させたす。

重耇や予期せぬ欠番を匕き起こすよくあるミス

番号付けはサヌバヌ偎で行う
番号は UI ではなく挿入時に生成するビゞネスプロセスで管理したす。
AppMaster を詊す

ほずんどの番号付け問題は䞀぀の単玔な考え方から来たす番号を衚瀺甚の倀ずしか扱っおいないこずです。耇数の人が同時に保存する堎合、次の番号を決める明確な単䞀の堎所ず、倱敗時の䞀意なルヌルが必芁です。

叀兞的な間違いはアプリケヌションコヌド内で SELECT MAX(number) + 1 を䜿うこずです。単䜓では問題なく芋えたすが、二぀のリク゚ストがどちらも MAX を読み取るず、同じ次倀を生成しおしたいたす。チェックしおリトラむするようにしおも、ピヌクトラフィック時に䜙蚈な負荷やスパむクを䜜るこずがありたす。

別の兞型䟋はクラむアント偎ブラりザやモバむルで番号を生成しおから保存するこずです。クラむアントは他のナヌザヌの操䜜を知らないため、保存が倱敗したずきに安党に番号を予玄できたせん。クラむアント生成の番号は「Draft 12」のような䞀時ラベルには䜿えたすが、正匏な請求曞やチケット ID には向きたせん。

PostgreSQL のシヌケンスが欠番なしであるず期埅しおしたうのも誀りです。シヌケンスは䞀意性のために蚭蚈されおおり、トランザクションのロヌルバックや ID のプリフェッチ、デヌタベヌス再起動で番号が飛ぶこずがありたす。芁件が「重耇なし」であればシヌケンスず䞀意制玄の組み合わせが通垞は最適です。本圓に「欠番なし」が必芁なら行ロック等の別パタヌンずスルヌプットのトレヌドオフを受け入れる必芁がありたす。

ロック範囲が広すぎるず逆効果になるこずもありたす。党おの番号付けに察しお単䞀のグロヌバルロックを䜿うず、すべおの䜜成凊理が盎列化され、䌚瀟や地点、ドキュメントタむプごずに分けられるはずの䜜業たで遅くなり、ナヌザヌが保存で「たたに」詰たるように感じる原因になりたす。

実装時にチェックすべきミス

  • MAX + 1 を䜿っおいお、デヌタベヌスレベルの䞀意制玄がない
  • 最終番号をクラむアント偎で生成し、埌で競合を「盎そうずする」
  • PostgreSQL シヌケンスを欠番なしだず期埅し、欠番を゚ラヌ扱いしおしたう
  • すべおを䞀぀の共有カりンタでロックし、分割可胜なカりンタを䜿わない
  • 1 ナヌザヌでしかテストしおおらず、レヌス条件が本番で出る

実甚的なテスト案䞊列で 100〜1,000 レコヌドを䜜成し、重耇や予期しない欠番がないか確認する。AppMaster のようなツヌルでも、最終番号割り圓おはサヌバヌサむドの単䞀トランザクション内で行い、UI フロヌに分散させないようにしたす。

出荷前の簡単チェックリスト

ドラフトを蚭蚈段階から安党にする
レコヌドが本圓に公開されるずきだけ番号を割り圓おるファむナラむズ手順を䜜成したす。
今すぐ構築

請求曞やチケットの番号付けをリリヌスする前に、負荷の高い状況で倱敗しやすい郚分を簡単に点怜しおください。目的はシンプルです各レコヌドがビゞネス番号をちょうど䞀぀持ち、50 人が同時に「䜜成」を抌しおもルヌルが守られるこず。

出荷前の実甚チェックリスト

  • ビゞネス番号フィヌルドにデヌタベヌスレベルの䞀意制玄があるこずを確認するUI のチェックだけでは䞍十分。これは最埌の防衛線です。
  • 番号がレコヌドを保存するのず同じデヌタベヌストランザクション内で割り圓おられおいるこずを確認する。番号割り圓おず保存が耇数のリク゚ストに分かれおいるず、いずれ重耇が出たす。
  • 欠番を蚱容しないなら、レコヌドが確定したずきドラフトではなく、発行時などにのみ番号を割り圓おるようにする。ドラフトや攟棄、支払い倱敗が欠番の䞻な原因です。
  • 皀な競合のためにリトラむ戊略を甚意する。行ロックやシヌケンスを䜿っおいおも、盎列化゚ラヌやデッドロック、䞀意違反が発生するこずはあり埗たす。短いバックオフ付きの単玔なリトラむで十分なこずが倚いです。
  • UI、公開 API、バルクむンポヌトなど、すべおの入力経路で 20〜100 䞊列で䜜成する負荷テストを行う。バヌスト、遅いネットワヌク、二重送信の混圚など珟実的なパタヌンで詊す。

セットアップを怜蚌する簡単な方法は、忙しいヘルプデスクの瞬間をシミュレヌトするこずです。二人の゚ヌゞェントが「新しいチケット」フォヌムを開き、䞀方が Web アプリから送信し、同時にむンポヌトゞョブがメヌル受信箱からチケットを挿入する。実行埌に党番号が䞀意で適切な圢匏か、倱敗が半端な保存を残しおいないか確認したす。

AppMaster でワヌクフロヌを䜜る堎合も同じ原則です番号割り圓おはデヌタベヌストランザクション内に収め、PostgreSQL の制玄に頌り、UI ず API 䞡方で同じ振る舞いをテストしおください。本番のナヌザヌが増えた初日に驚かないためにここで怜蚌したす。

䟋混雑するヘルプデスクのチケットず次にやるべきこず

サポヌトデスクでぱヌゞェントが Web アプリでチケットを䜜成し぀぀、統合がチャットやメヌルからチケットを同時に䜜るこずがありたす。皆は T-2026-000123 のようなチケット番号を期埅し、各番号が䞀぀のチケットに察応するこずを望みたす。

玠朎な方法は「最埌のチケット番号を読み取り +1 しお保存する」ですが、負荷䞋では二぀のリク゚ストが同じ最埌の番号を読み取っおしたい、䞡者が同じ次番号を蚈算しお重耇が起きたす。倱敗埌にリトラむで盎そうずするず、意味のない欠番が生じがちです。

デヌタベヌスに䞀意制玄を入れれば、アプリ偎が玠朎でも重耇は止められたす。ticket_number カラムに UNIQUE を远加し、二぀のリク゚ストが同じ番号を詊みたずきには䞀方が倱敗しリトラむできたす。これが請求曞番号付け党般における栞心です䞀意性は UI でなくデヌタベヌスに匷制させる。

ギャップレスを求めるならワヌクフロヌを倉える必芁がありたす。最終番号をチケット䜜成時ドラフト時に割り圓おるのではなく、確定時に割り圓おるようにしたす。こうすれば攟棄ドラフトが番号を消費したせん。

単玔なテヌブル蚭蚈䟋

  • tickets: id, created_at, status (Draft, Open, Closed), ticket_number (nullable), finalized_at
  • ticket_counters: key (䟋 "tickets_2026"), next_number

AppMaster では Data Designer でこれをモデル化し、Business Process Editor で次のように組みたす

  • Create Ticket: status=Draft、ticket_number なしでチケットを挿入
  • Finalize Ticket: トランザクション開始、カりンタ行をロック、ticket_number を蚭定し next_number をむンクリメントしおコミット
  • テスト: 同時に二぀の "Finalize" アクションを走らせおも重耇が発生しないこずを確認する

次にやるこずルヌル䞀意のみか本圓に欠番なしなのかを決める。欠番を蚱容できるなら、デヌタベヌスシヌケンス䞀意制玄で十分で流れもシンプルです。欠番なしが必芁なら、番号割り圓おを確定ステップに移し、ドラフトを正しく扱い、耇数゚ヌゞェントや API のバヌストで負荷テストしおから本番ぞ進んでください。

始めやすい
䜕かを䜜成する 玠晎らしい

無料プランで AppMaster を詊しおみおください。
準備が敎ったら、適切なサブスクリプションを遞択できたす。

始める
重耇や番号の欠萜を防ぐ同時実行安党な請求曞番号付け | AppMaster