質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Q&A

解決済

4回答

2115閲覧

データベースの同時インクリメント更新で整合性を保つには

rtgsdfsdg

総合スコア174

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

0グッド

1クリップ

投稿2021/08/16 04:35

質問内容は見出しの通りです。
例えば、あるサイトにアクセスがあるたびにあるデータベースに含まれる数値型の値に1を足していくという実装があるとします。もしそのサイトに全く同タイミングでアクセスがあると、同時に値を参照しそれに1を足すわけですから本来<元の数>+2になるべきであるところ結果<元の数>+1になると思います。
こういう問題は一般的に何という名称がつけられていますか?また、整合性を保つには一般的にどのような対策が取られているのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/08/16 04:38

なにか調べてみたものはありますか?
guest

回答4

0

ベストアンサー

こういう問題は一般的に何という名称がつけられていますか?

単に排他制御不備でもよいですが、TOCTOU競合と呼ばれます。

Time of check to time of use - Wikipedia

また、整合性を保つには一般的にどのような対策が取られているのでしょうか?

一般的にということであれば、排他制御です。

ただ、特定の列を +1 するだけであれば、以下のように単一のSQL文で実行すれば問題ないと思います。

UPDATE table1 SET columX = columX + 1 WHERE -- 以下略

データの取得と+1を別のSQL文で実行する場合は、トランザクションと当該行のロックで対応します。

投稿2021/08/16 06:26

ockeghem

総合スコア11705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

全く同タイミングでアクセス

厳密にいえば全く同じタイミングというのはありません。
処理Aが参照中に処理Bが発生する可能性はありますが

トランザクションで処理をすればある程度競合を防げますが
可能であればテーブル側にユニーク制限をかけておくことです
またインクリメントだけを目的としたカラムは
途中でデータ修正や削除があった場合に競合や欠番が発生する
可能性があるためあまり現実的ではないので、
auto_incrementなどで順番を確保した上でランク付け関数などで
都度計算するほうが現実的です

投稿2021/08/16 04:53

yambejp

総合スコア116724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

DB側の仕組みでオートインクリメントをするとか
DB側でシーケンス払い出すとか

具体的な対策はDBによります。
そもそも重複する可能性のある実装になってしまっている時点で設計の考慮不足です。

こういう問題は一般的に何という名称がつけられていますか?

問題も何も実装の通り動いているのでバグでも何でもありません。
名前も付けようがないのでは(あったとしても先の通り設計考慮不足の実装なので何とも)
「キーが重複するような実装になっている(duplicate key)」とそのままです。

投稿2021/08/16 04:37

編集2021/08/16 04:44
m.ts10806

総合スコア80875

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0xVERS

2021/08/17 11:49

TOCTOU競合と呼ばれるそうです。覚えておいてくださいね。
m.ts10806

2021/08/17 12:08

名前の有無をメインとして言及してるつもりはないです。 設計の不備が問題です。ただ、その名前を出した本人でない人に言われるのは釈然としません。 (低評価理由がそれなら問題の本質はそこではないということは言いたい)
0xVERS

2021/08/17 12:22

単に初心者に対して不正確な事実が伝わって欲しくなく感情的な煽りになってしまいました。気分害して申し訳ないです。でも一つだけ言わせてください。低評価僕じゃないです。笑
m.ts10806

2021/08/17 12:31 編集

はい。おそらく0xVERSさんが低評価した人ではないというのは活動の感じから想像はできます(低評価とコメントのタイミングが同じなので一瞬疑いましたが) 同じ理由での低評価なら、という前提が抜けていました。失礼。
guest

0

レコードに対する排他制御で処理します。
例えば、連番を採番したい場合。
テーブルに採番用のレコードを1件作成し、これに番号項目を設けます。
1回目→値:1。レコード確保、1番を取得し、次アクセス用に+1でUpdate、開放
2回目→値:2。レコード確保、2番を取得し、次アクセス用に+1でUpdate、開放
3回目→値:3。レコード確保、3番を取得し、次アクセス用に+1でUpdate、開放
同時に、アクセスあった場合には、データベースが自動的に優先順位を付けて、順次処理します。後回しになったアクセス処理は、前の処理が終了するまで、待ち合わせがされます。この部分の制御も、データベースが全て自動で管理してくれます。
一定時間待ち合わせても、レコードの開放が成されずに、使用する事が出来なかった場合には、使用中でタイムアウトエラーとなります。

投稿2021/08/16 07:02

編集2021/08/16 07:03
tosi

総合スコア553

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問