@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

データベースの楽天的排他処理とバッチ処理

1
投稿者投稿内容
ognac
ベテラン
会議室デビュー日: 2005/06/21
投稿数: 65
投稿日時: 2005-06-21 15:41
データベースの楽天的排他処理とバッチ処理

いつも、ROMばかりさせて頂いています。
MVP諸兄の知恵には脱帽です。
初投稿になります. ognacと申します.以後よろしくお願いいたします.

本題です。
一般的な処理をするデータベースアプリ(Win.Formアプリ)を開発しました。
オンラインサービス時間内は,
一般端末からのマスター類(顧客マスタ,商品マスター等)保守と業務データ入力(売上伝票入力/仕入伝票入力等)を可能にしています.
オンラインサービス時間後は,一般端末からの更新を不可にして, 日次バッチを走らせて, トランザクションデータの集約バッチを処理しています.
マスタ関連情報として, 日時時点での集計結果を更新しています.

極々一般的な処理なのですが, データ入力を 24時間開放する事になり,ハタと迷路に突入しました.
悲観的ロックの時は
データ入力中にバッチが走ると, 排他関連で.デッドロックになるか, 該当データが未更新のまま残る.
(ADO.NET は楽観的ロックなので, 実装は旧ADOでの時でしょうが)
楽観的ロックのときは, 入力している人は,更新アクションのときに,データが更新されていることを知る.

まぁ,頭では理解できるのですが, 違和感と戸惑いを感じるのです.
バッチ開始時点で, 更新画面が開いている端末に通知する, もしくは,
その時点で, Lockが掛かっているレコードの存在を調べる (楽観的ロックだと,そもそも無理か)
などを考えていると堂々巡りに嵌りました.


昨今, 24時間稼動のシステムは多々あると思います, 日次バッチはどうしているのでしょう?
 そもそも,日次バッチが必要なシステム自体に問題があるのでしょうか,
トランザクションレベルで,処理し,日次を不要にする?

確かに,RDBにはオンラインバックアップが存在し,その時点への復元はできるようです. しかし,
バックアップ時点でどの端末がaccess中だったのかは簡単には把握できないみたいです.

このような問題はどのように解決なさっておられるのでしょうか.


甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2005-06-21 18:17
貴方の心配していることの多くは、たぶん無用の事です。

「楽観的ロックのときは, 入力している人は,更新アクションのときに,データが更新されていることを知る」のはその通りです。知った結果、どうすべきかは貴方の定めた仕様によるところです。在庫がマイナスになろうが継続するのか、問答無用でエラーとするのか、特定条件を満たすときは継続するのかは貴方の決めることです。受注業務なら「在庫がマイナスにならない限り継続」しても問題ないでしょう。

ADO.NETでも悲観的ロックを使うことはできます。楽観的ロックを使うことが多いのは、断続的に接続/切断を繰り返すWEBアプリケーションでは悲観的ロックを使うことができないからです。今回はWindowsアプリケーションなのですから、悲観的ロックを使っても不都合は(サーバーの負荷以外には)無いでしょう。

バッチ処理と入力処理を平行して行えるか否かは、テーブル構成による所です。バッチ処理の具体的な内容やテーブル構成が分からないと、なんとも判断のしようがありません。逆に言えば、テーブル構成を問題が無いように部分的に再設計する必要があるかもしれません。その流れの中で「トランザクションレベルで処理する」という判断も有り得るでしょう。

すくなくとも「バッチ開始時点で, 更新画面が開いている端末に通知する」なんて作りでは「24時間開放」とは言えませんよね。

「バックアップ時点でどの端末がaccess中だったのか」を判断する必要は、普通はありません。バックアップ時点でCommitされていないデータは普通は失われますし、Commitされているデータは残ります。逆に言えば、本来はトランザクションが完結するまでCommitしてはいけないのです。楽観的/悲観的ロックに限らずね。
ognac
ベテラン
会議室デビュー日: 2005/06/21
投稿数: 65
投稿日時: 2005-06-21 23:20
>貴方の心配していることの多くは、たぶん無用の事です
ありがとうございます.一安心しました。

<(楽観的ロックの時に),更新画面が開いている端末が存在しても,バッチを走らせて,
入力値が無効になっても, その旨が入力者に伝わればいい> と割り切ることがポイントですね. 入力者が,入力データが消えたと騒がれる事を,怖がっていた事に気づきました.

また, Oracleの For updateなどの行ロックも, ADO.Netで可能なようで(考えたら当然ですが), 悲観的ロックになりますが, その時は, 該当レコードはバッチ更新できません.
ということは,このようなテーブル設計自体がおかしい訳ですよね.
一時ワークなどを媒体にして, バッチ処理の対象テーブルはロックが掛かっていない
状態を作るようなテーブル設計が肝要なのですね.


どうも,エンドユーザーに対して,八方美人になりすぎて,本質を見失いかけてました.
1

スキルアップ/キャリアアップ(JOB@IT)