「登録したはずなのに、入っていない」

長く使ってきたAS/400のアプリで、そんな現象が起きた。

僕が開発した、名前などの基本情報を十人分ずつまとめて入力するアプリだ。

このアプリは、二人が別々に入力し、その結果を突き合わせて、一致した情報を本番データに格納する仕組みだった。同じ人が二回打つ、という話ではない。

二人の入力を確かめる工程を含めて、日々の仕事になっていた。

当初は仕事を担当ごとに分け、それぞれの入力範囲を分担していた。その運用では、別のまとまりの入力との競合は起きていなかった。

ところが、その後、まとめて入力する運用へ変わった。

稼働してから、およそ30年たってからのことだ(笑)。

ある十人分の最後のほうと、別の十人分の最初のほうが被る。調べてみると、この入力範囲の重なりが問題になっていた。

二人の入力結果を突き合わせる確認と、ほかのジョブの更新と競合していないかという確認は、ここでは分けて考えたい。

長く動いていたアプリでも、使い方が変われば、それまで表に出なかった問題が現れるんですよね。

受付の入力に追いつかれたくない

当時、ほかの処理では、先にロックを取って競合する更新を待たせる、悲観的排他制御を使っていた。

ただ、この一括入力では、受付担当者の入力の速さも大切だった。十人分をまとめて扱う仕組みを、入力を待たせるものにはしたくない。

そこで、このアプリには楽観的排他制御を入れた。

僕が行ったのは、DBから読み取った時点の情報を配列に保存しておき、更新するときに十人分を一人ずつ、ほかのジョブで変更されていないか確認することだった。

競合のチェックで変更が見つからなければ、そのレコードの更新を進める。

ほかのジョブで変更されていたレコードだけは、自分のジョブから更新せず、画面にメッセージを出す。

十人のうち一人が競合したからといって、ほかの人の入力まで、まとめて無駄にしたくなかった。

どこまでを、やり直してもらうか

楽観的排他制御という名前だけだと、少々のんきな仕組みに聞こえるかもしれない。

このアプリで行ったことは、更新時に変更の有無を確かめ、競合したレコードの更新を見送ることだった。そして、競合していないレコードの入力は活かす。

「誰かと被ったから、十人分全部やり直してね」では、入力した人が困ってしまう。

守りたかったのはデータと、そこまでに人が行った作業だった。二人がそれぞれ入力して確かめる、その手間も含めて。

いま取り組んでいる別の仕事でも、楽観的排他制御を使っている。ただ、原理が同じでも、競合しそうな頻度や入力の速さを考えると、実装まで同じにはならない。

もし今回話した一括入力に、その別の仕事と同じ方法を持ち込んでいたら。

受付から「おっそっい〜!」の大合唱が聞けたと思う(笑)。

これは、実際にその苦情を受けたという話ではない。あの入力速度を知っている僕の想像だ。

行った作業を、できるだけ無駄にしない。

自分がやられて嫌なことを、使う人にも味わわせたくない。その考え方が、僕には染み付いている。

どこで競合を確かめ、どこまでを更新し、どの部分を見直してもらうのか。僕にとって排他制御は、画面の前で仕事をしている人を思い浮かべながら決めるものなんですよね。

出典・補足

本稿は、2026年11月1日に本人が語った、過去に開発したAS/400アプリの記憶を中心に構成した。約30年という期間も本人の記憶による。架空の障害対応や利用者の発言は加えていない。

手順は当時の設計の考え方を紹介するもので、ソースコードの再現や実装手順書ではない。比較する情報の範囲や、確認から更新までの排他の詳細は本稿では扱わない。

参考:IBM Documentationには、楽観的排他制御の一例として、取得時の値を更新条件に含めるSQLの方式が説明されている。この資料は概念を補うもので、僕の当時の実装がSQLだったことを示すものではない。

IBM Documentation: Select a stringent level of commitment control(IBM i 7.4)

WRITTEN BY 太城 義雄(たき よしお)

IBM i / AS/400を愛するSE