Foros: Open Discussion (Thread #25537)

【バッチFW】マルチスレッドのトランザクション処理 (2010-02-26 11:01 by hoge #48926)

お世話になります。

早速ですが、

現状、分割キーを使用して、マルチスレッドでバッチ処理を動かしています。
そこで、マルチスレッドの場合複数トランザクションとなってしまうので、1回DDLを発行してしまうと
コミットされてしまいます。

マルチスレッドで、シングルトランザクションの設定は出来ないのでしょうか。

かなり、困ってます。

どうか、是非、ご教授の程、よろしくお願い致します。

Responder al #48926×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: 【バッチFW】マルチスレッドのトランザクション処理 (2010-02-26 13:29 by taromaru #48930)

> 1回DDLを発行してしまうとコミットされてしまいます。
これはタイプミスなのかどうか判断に迷いましたが、
DDL(CREATE文やTRUNCATE文等)はそもそもロールバックできないので、
1回発行すれば、コミットされます。
トランザクションがスレッドごとに独立していることとは関係ありません。

DDLではなくDMLであった場合は以下を参照してください。

機能説明書にも書いてありますが、
全ての子ジョブ(スレッド)を単一のトランザクションとすることは出来ません。
(「BA-01 トランザクション管理機能」の「解説」より。)

もし異なるスレッドが同一のトランザクションに割り込んだら、
適切にシンクロナイズしていたとしても、
・読み取りはダーティーリード(他のトランザクションがコミットする前のものが見える)に近い状態
・ロールバックしたら何がロールバックされるのか見当が付かない
という状況になってしまいます。
(そういう状況に陥らないようになっています。)

更新系処理のトランザクションを1本にしたい場合は、
・分割ジョブにしない
というのが最も簡単な方法ですが、
余っているマシンリソースを活用して実行時間の短縮を試みたい場合は、
・参照系処理と演算処理を分割ジョブで実施し、更新用データをファイル出力する
・次に、分割ジョブでない通常のジョブで、ファイルから更新用データを取得し、DBを更新する
という方法も考えられます。
Responder al #48926

Responder al #48930×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: 【バッチFW】マルチスレッドのトランザクション処理 (2010-02-26 13:54 by hoge #48931)

taromaru 様

迅速なコメントをありがとうございます。

> 1回DDLを発行してしまうとコミットされてしまいます。
これは、DMLです。
誤記をしてしまいました。
すいませんでした。

分割ジョブではトランザクションは1つに出来ないんですね。
ありがとうございます。

また、質問は少し変わるのですが、
現状、SQLから取ってきた値を分割キーとして設定しております。
そのとき、分割ジョブで別々にトランザクションが走ると、コミットされてしまうので、
どのようにリトライ処理を行えば良いのでしょうか。
(※SQLの取得件数は、コミットすると変動する場合も有り)

シングルだとロールバックはされる事は確認しております。

何か、よい案があれば教えてご教授お願いできないでしょうか。

※尚、パフォーマンスがかなり求められている処理なので、分割キーで行いたいです。
Responder al #48926

Responder al #48931×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: 【バッチFW】マルチスレッドのトランザクション処理 (2010-02-26 14:25 by taromaru #48932)

> どのようにリトライ処理を行えば良いのでしょうか。
A. リスタート機能(BE-04)を利用する
B. (もし、リスタート機能が「要件に合わない」「難しい」と感じたら)以下のようなジョブとする。

(ここからが、「以下のようなジョブ」の説明です。)
更新処理が完了したデータが次回のジョブ実行において抽出されないよう設計しておくと、
「エラー発生時にはリランすればOK」というジョブになります。
こうなっていれば、通常ジョブ、分割ジョブ等関係なく、
リトライ処理は、ジョブ丸ごと再実行でOKということになります。

更新処理が完了したデータが次回のジョブ実行において抽出されないような設計の例としては、
・バッチ処理時に、バッチ処理要求のキューの役割を持った一時レコードを削除する
・バッチ処理対象レコードにバッチ処理ステータス用カラムを用意し、バッチ処理時にそのカラムを更新する
といったものがあります。
Responder al #48931

Responder al #48932×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: 【バッチFW】マルチスレッドのトランザクション処理 (2010-03-01 13:11 by hoge #49051)

お返事ありがとうございます。

>A. リスタート機能(BE-04)を利用する
こちらは、条件が合わないので、やめております。

>・バッチ処理対象レコードにバッチ処理ステータス用カラムを用意し、バッチ処理時にそのカラムを更新する

こちらは、テーブルのカラムには今から、変更はいれられない状態ですし、取得してくる対象テーブルが多い為、なしとさせて下さい。

>・バッチ処理時に、バッチ処理要求のキューの役割を持った一時レコードを削除する

Bについてなんですが、具体的にどういう事でしょうか?
Responder al #48926

Responder al #49051×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: 【バッチFW】マルチスレッドのトランザクション処理 (2010-03-01 14:31 by taromaru #49052)

>Bについてなんですが、具体的にどういう事でしょうか?

2回同じデータを処理してはならないタイプのジョブでは、
どこまで処理をしたかをDBに持つ必要があります。
そのように設計されていなければ、確実に未処理データだけを処理するということが出来ないからです。
(2回同じデータを処理してもよいタイプのジョブであれば、
どこまで処理したかという情報は不要です。
リトライの方法は、単にジョブをリランするだけです。)

「どこまで処理をしたか」という情報を
カラムとして持つのが、
「・バッチ処理対象レコードにバッチ処理ステータス用カラムを用意し、バッチ処理時にそのカラムを更新する」
という方法で、
レコードで持つのが、
「・バッチ処理時に、バッチ処理要求のキューの役割を持った一時レコードを削除する」
という方法です。

レコードで持つ方法は、
バッチの処理対象データが出来る際に、バッチ処理要求用のレコードを追加(業務処理でINSERT)し、
バッチの処理時にそのレコードを削除するという方法です。

もし、エラー時の運用が設計の観点から漏れていた場合は、
バッチ処理要求レコードのINSERT文を追加(テーブルがなければテーブルも追加)するより、
デフォルト値を持つカラムを追加する方が簡単かと思います。
(業務処理のINSERT文に列名さえ書いてあれば、業務処理には手を入れなくて済むので)
ただし、
処理の内容やテーブルの構造、
既存のSQL(INSERT文に列名が書かれていないので下手に列を追加できない等)によっては、
一概にそうとも言えないケースがあるかもしれないので、
こればかりは、比較的容易に実現できる方法(もしくは、実現可能な方法)を検討していただく必要があります。
Responder al #49051

Responder al #49052×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: 【バッチFW】マルチスレッドのトランザクション処理 (2010-03-01 18:39 by hoge #49059)

ご返答ありがとうございます。

カラムを追加し、更新フラグなどを設けてリトライ処理を行おうと思います。
本当にありがとうございました。

Responder al #48926

Responder al #49059×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar