
三菱東京UFJ銀行で一部の送金が行われないというシステムトラブル、原因は終了判定の不適切な仕様 67
ストーリー by hylom
そんな設計で大丈夫か 部門より
そんな設計で大丈夫か 部門より
あるAnonymous Coward 曰く、
4月30日、東京三菱銀行で「定期自動送金サービス」を扱うシステムでトラブルがあり、約2万3000件、合計約30億円が送金できないという問題が発生した(日経ITpro)。
トラブルの原因は、終了条件の判定を行う際の仕様が不適切だったためのようだ。このシステムでは1000件単位で契約内容をチェックして送金処理を実施するとのことで、その際にすでに解約済みの契約については「データ無し」として処理するという。このとき、1000件連続で「データ無し」になるとすべての処理が完了したものとして処理を終了する仕様となっていたそうだ。問題が発生した4月30日の処理では6万4162件が処理対象だったが、その処理途中で1000件連続で「データ無し」が発生して処理が終了され、未処理の契約が生じたという。三菱UFJ側は「1000件を超える解約があった可能性がある」としている。
細かいデータ内容などは明らかにされていないため詳細は不明だが、解約が1000件を超えるということは想定していなかったのだろうか。
面倒だから計算しないけど (スコア:4, 興味深い)
64000件のデータで、もし無作為で1000件連続して解約データが含まれていたのであれば、解約率は99%越えてるはずです。
なので元々解約者が多く含まれるようなデータなのか、解約者が並びやすい条件でソートしているのか、どちらかでしょう。
Re:面倒だから計算しないけど (スコア:2)
あくまで理論上の話だけど、
これ、「3月で契約終了」のデータが多数あったと思うのです。
そのうち、例えば2年契約とかで「同じ時期にスタートした契約がたまたま同じ時期に終了する」可能性は、そんなに低くないと思われます。
それが千件並ぶのはよっぽどのことだと思うけど、
ありえない確率とは思えないのです。
Re:面倒だから計算しないけど (スコア:4, 参考になる)
一応簡単に計算すると、1000件連続で解約者が並ぶ確率は、解約率が99%としても
0.99^1000=0.000043
これを64000件分のバッチ処理、1000件を64回まわす間に落ちる確率は0.002755で0.28%弱しかありません。
たとえ「3月末契約終了」が多く解約率が99%だとしても、64000件の処理中に1000件連続する確率は0.28%で、実際には解約率はもっと低いはずなのでちょっと起こり得ないかな、と。
なので、他のACの方が指摘しているような、1000件とかまとまった件数を契約している業者が解約したとか、そういうのが無いと厳しいかと。
Re:面倒だから計算しないけど (スコア:2)
Re: (スコア:0)
単体で見れば低い確率でも、それを数十回と繰り返してきたわけで
Re: (スコア:0)
千件以上一度に契約していた業者が契約終了したという可能性はあると思います。
Re: (スコア:0)
消費税率の変更という大きい事象があったわけで、それに合わせて金額変更に伴う契約終了→新規契約が多数発生した可能性は考えられますね。
Re: (スコア:0)
自動送金なんて使うのは電気ガス水道がほとんどですよね。
となると、3月の卒業なんかで解約して4月度の送金でトラブったんでしょうね。
Re:面倒だから計算しないけど (スコア:2)
Re: (スコア:0)
Re: (スコア:0)
電気ガス水道は定額じゃないよ。
Re: (スコア:0)
Re: (スコア:0)
前処理でデータをソートしてそうなので
年とか店とか、何か大きな節目があったんじゃなかろうか。
あとは、「無限ループとデッドロックを排除する」号令のもと、
試行回数の上限にそれっぽい値をハードコードしてたとか
そんな感じじゃないかと妄想してみる
Re: (スコア:0)
勘定系でソートってあり得ない気が。
Re: (スコア:0)
素人考えですけど、接続先が揃っているといちいちコネクション張り直さなくていいとかないんですかね?
Re:面倒だから計算しないけど (スコア:1)
そういう場合、通常は
・全件読み込んで振り分け処理。接続先毎のデータファイル作成
・それを1ファイルずつ順に処理
という風にします。
ソートは、うかつにつくるとメモリ足りなくなったりするし、
まじめに(件数が多い時には)マージソートするように実装すると、
結局振り分けするよりコストが高くなるので。
Re: (スコア:0)
全件処理だからソートする領域が取れないか、時間がもったいないかで、ベタでfetchしては処理してるんじゃないかと想像してみた。
いや、条件がなければ多分契約順になるから、大雑把には年齢順になる=頭の方から歯抜けになっていくか…。
話にならない (スコア:0)
連続性が担保されているデータならともかく
どう途切れるか不明なデータの連続性で何か判定しようとするのは狂っている
Re:話にならない (スコア:3)
たぶん
while(処理件数 > 0) {
処理件数 = 送金処理(リスト#next1000件);
}
みたいなループなんだと思う。
このループ処理の実装者と送金処理の実装者が違うなら、まぁ分からなくもないかなぁ。
狂ってるというか、仕様をちゃんとチェックせずに実装しちゃった系のよくある普通のバグでしょ。
Re:話にならない (スコア:1)
とにかく1000件読んできて、1件も処理すべき内容がなかったら終了というのが
エラー検出ではなく正常な終了判定なんですかね。
不思議なのは、自動送金の処理プログラムが何件処理すべきか分かっていないということ。
三菱東京UFJ銀行では、顧客から依頼されている自動送金の依頼数をコンピュータシステム上に
持っていない(実際に処理してみないと分からない)ということだろうか?
# 「1度に読み込む件数を5000件に増やしたのでもう取りこぼすことはありません」となったりして。
Re:話にならない (スコア:2)
日次で同じ程度の件数が上がってくるシステムやったけど、確実に終わりはあったけど。
Re:話にならない (スコア:1)
「次のn件を取得する」みたいに、別のところからデータだけ返してくるようならありえますね。
ただ万が一そんな変な連携があったとしても……まずだーっと取得して、保存して、そいつを1つ1つ処理していけば問題ないのですが。(でないとリトライするのに、またデータ受信から始まっちゃって面倒だから!)
==========================================
投稿処理前プレビュー確認後書込処理検証処理前反映可否確認処理後……
Re: (スコア:0)
高速化や別件対応でありそうな「正常終了判定」という印象。
某都市銀行のバグ管理簿みたことあるけどテスト漏れとしか思えないバグばっかだった。
「よくある普通のバグ」に全面的に賛同だわ。
Re: (スコア:0)
> 1000件連続で「データ無し」になるとすべての処理が完了したものとして
こんな終了条件が必要なケースが思いつかない
バグというより余計な処理入れてるわけで
高速にもならんしスタブミスとしても不可解
Re: (スコア:0)
うーん、ハード増強したから一括処理件数増やしたらシステムダウンとか
端末で特定のミス2回連続したら無限ループとか
紙伝票の余白が終了条件で余白がなければ白紙挿入という仕様で白紙が連続したら処理停止とか
そういうマヌケなバグいっぱいみたんで思い付かないといわれてもありそうとしか。
増税直後で何かしらシステム変更してるだろうし。
1000件連続データなしはうかつだけど、一定アイドルで次の処理はあった気がする。
Re: (スコア:0)
# 「1度に読み込む件数を5000件に増やしたのでもう取りこぼすことはありません」となったりして。
いやいや、トラブルが起きたのは4月30日。
三菱東京UFJ銀によると、5月1日以降の処理について、同様の事象が発生することはないという。
翌日にシステム改修が完了するなんて疑問が大きすぎる。
5月分の自動送金伝票を皆で数えて、解約が1000件連続しないことを確認しただけだったりして。
Re:話にならない (スコア:1)
おそらく、逐次のチェック処理だと、DBとか使わずにファイルから読み込んでるんだと思う。
そしてデータの最後を表す番兵レコードがいるんじゃないかな。
そうすると、1000件単位に区切って処理しようとした場合に、全数が1001件だったりすると
2単位目は対象が番兵レコード1件だけとなって、つまり処理件数0件だからループ終了
みたいなへんてこ仕様なんだと思う。
で、テストでもその条件でループ終了することを確認してOK、みたいな。
そうだとしたら設計が良くないし、ついでに設計者同士の連携も良くないんでしょう。
Re: (スコア:0)
番兵レコードの存在を知らなかったんじゃないかな。きっと、EOFを過ぎてファイルからバッファに1000件分読み込んで処理を行うと処理件数が0に(偶然に)なることを利用して、EOFを過ぎたことを検出して終了するようなプログラムを書いていたのではないかと思った。
意味がわからない (スコア:0)
解約済みはデータ無しになる。
契約内容のチェックが終わったものはデータ無しになる。
1000件連続でデータ無しになると次の1000件の契約内容をチェックする。
ということは
解約済みが1000件あった場合に1000件のデータ無しになる。
1000件の契約内容のチェックが終わった場合に1000件のデータ無しになる。
どっちも同じと思うんだけど。
Re:意味がわからない (スコア:1)
難しく考えるからかと。
想像が入りますが、
データを解約済み(解約マーク)にしたあと、データそのものは空き番になってるのですよ。
だから1000件のデータと言っても「何年も前に解約されたデータ」が含まれると。
積もり積もって、1000件連続の解約しか無いデータが出来た。そらそうです。
データなしが連続したら終了にするというのは、最終レコードが特定できないデータが有った場合やることです。
しかし解約データをデータ無しとカウントするのはアホのすることです。
Re: (スコア:0)
契約内容のチェックが終わったものはデータ無しになる。
ん?? ↑はどこに書いてあったんですか?
テレビドラマで見た (スコア:0)
バグを利用した金融庁のエックスデー シミュレーションテストだったんだよ!!!
# Ω ΩΩ な、なんだってー
興味深いといえば興味深い (スコア:0)
三菱ともなれば、膨大な人と金をかけて、仕様を検査しテスト項目を積み上げたはず。
どういう経緯で、「1000件連続で「データ無し」で終了」という論理が紛れ込み、検査をすり抜けたのか、
さらに今回の問題発生による、原因探求と再発防止用の見直しがどんな内容と規模なのか、知りたいですね。
Re:興味深いといえば興味深い (スコア:2)
膨大な人と金はかけましたが、その人が誰もきちんとチェックしなかったということでしょうね・・・
# 人が多くなったら責任感が薄れて誰もきちんとやらなくなると思うんです
# 少なすぎても投げやりになって同じっぽいですが
新人。プログラマレベルをポケモンで言うと、コラッタぐらい
Re:興味深いといえば興味深い (スコア:1)
実装者『これ、解約データが1000件連続するとアウトですけど良いんですか?』
よく分かっていない上司『いいよいいよ、1000件も解約データが連続することなんて無いでしょ』
という会話があったであろうことは想像に難くない…
Re: (スコア:0)
>人が多くなったら責任感が薄れて誰もきちんとやらなくなると思うんです
だからうちの会社は在庫が合わないんだよ!
無責任な営業を動員して一日で棚卸しなんてするよりは、
日雇いの素人バイトでも雇った方がまだマシ。
Re:興味深いといえば興味深い (スコア:1)
三菱だと適当に作りそう。
三和だと抜かりなく作りそう。
統合して劣化していったんだろうな…。
Re:興味深いといえば興味深い (スコア:1)
>三菱ともなれば、膨大な人と金をかけて、仕様を検査しテスト項目を積み上げたはず。
と思ってたけど実体はあのザマでござる。
Re: (スコア:0)
広報が仕様と実装の違いを理解していないだけという一縷の希望はありませんか?
「現在実装はこうなっている」を「仕様」として発表した、みたいな
#どうせCOBOLだから、どう頑張っても似たような実装になるはず
#「コントロールブレイク」的な、よくあるけど間違えやすい処理の典型例だと思う
Re: (スコア:0)
三菱ともなれば、膨大な人と金をかけて、仕様を検査しテスト項目を積み上げたはず。
ところがどっこい、大手SIerでもレビューすらしてないだろって品質の仕様書を設計工程に回してくるんですよ。
しかも信じられないことに、顧客もそんな品質の仕様書を承認しちゃってる。
Re:興味深いといえば興味深い (スコア:1)
Re:興味深いといえば興味深い (スコア:1)
MDISはできるなら銀行のシステムに食い込みたいでしょ。
何しろ銀行は金持ってるから。
けど、IBM(とオマケのDCS)の牙城が堅くてなかなか、というのが正直なとこじゃないの。
#あと、MINDとかも
Re: (スコア:0)
図書館システムのMDISさんですよね? (岡崎市立中央図書館事件 [wikipedia.org])
三菱銀行のほうが嫌がりそうですが。
Re:興味深いといえば興味深い (スコア:1)
実害レベルで比べるとどっちがどっちだろ。
Re: (スコア:0)
『上流工程』の人間ほど、普段あいまいな言葉で済ませていることが厳密に定義しようとするとどれだけ大変かということを理解していないですからね… (個人の印象です)
誰だよ特定のデータで終端とか考えた奴 (スコア:0)
printf( "%zu", strlen( "abcd\0efgh" ));
Re: (スコア:0)
ふつーPascal文字列ですよねー(棒)
Re: (スコア:0)
pop3「サーセンw」
Re: (スコア:0)
Re:回避策 (スコア:1)
s/1000/10000/g
しとけばしばらくはしのげそう。