
再現できない障害ほど厄介なものない。
テーブルのバッファリング
SAPのテーブルにバッファリングタイプというものがあります。
詳しくはこちら

簡単に言ってしまえばパフォーマンスをあげるための設定です。普段はあまり意識しないので、知らなくても大丈夫と言えば大丈夫な設定。だけど、知っておきましょう。痛い目を見ました。
パフォーマンスをあげるための設定ですが、それゆえ、ひとつやっかいな問題があります。テーブルデータを取得時に、最新のデータが取得できない可能性があります。リアルタイムにデータが反映されないのです。
夜間ジョブで障害が発生
どのような障害の説明する前に、どのようなJOBを回していたのか説明します。
ごくごくシンプルです、プログラムAのあとプログラムBをさせました。下記のような感じです。
【プログラムA】
データを取得し、必要なデータだけに絞って、
TVARVCを更新
【プログラムB】
更新したTVARVCの変数を使用して実行
このJOBは毎日毎日動いていました。何の問題もなく、動いていました。
ところが、ある日、プログラムAで必要なデータに絞っているにもかかわらず、プログラムBで対象から漏れていることが、翌日、判明しました。
バリアントを見ても、しっかりと対象に含まれているにもかかわらず、プログラムBで処理されなかったのです。必死にプログラムBを調査しました。対象になっているにもかかわらず、処理漏れしているのですから、何かの条件に合致して処理されないケースがあると仮説を立て、徹底的に調べました。
しかし、分からず。。。。再現待ちに。(なさけない。。。)
すると、半年ぐらいたったでしょうか。。。また同じ障害が発生しました。
こんなこともあろうかと、ログが出力されるように仕込んでおきました。そこで分かったのは、前日のバリアント変数でプログラムBが実行されていることです。
プログラムBはまったく問題ではなく、プログラムAが怪しいということなりました。しかし、朝出社してバリアント変数を確認すると、正しい値になってます。
プログラムAも正しく動いているのです。
ちゃんとCOMMIT AND WAIT しているのに、なぜかプログラムBが実行するタイミングで TVARVC の古い値をもってきてしまうのです。
まぁ初めに答えを書いたので、皆さんご理解されていると思いますが、 TVARVC はバッファテーブルだったので、 プログラムB実行時に、最新のデータが取得できなかったのです。
暫定かつ恒久対応として、プログラムAとプログラムBの間に5分間WAITするという苦肉の策で逃げました。
初回の 障害が発生した時点で TVARVC がバッファテーブルであることに気付くべきだったのですが、すっかり忘れてました。

この障害の厄介な点は、再現できないという点。
それともう一つは、単体テスト、結合テストでも見つけきれない点。
SAP ECCの障害シリーズ、今後も書きたいなぁ。
追記 2020月4月2日
SELECT文のオプションにBYPASSING BUFFERがあることを教えて頂きました!これで障害回避が可能です!

多謝!