メインコンテンツへスキップ

レコードロック解除待ちが解除されない時、アボートさせてそれを把握し、処理制御

コメント

33件のコメント

  • ISHIJIMA

    遅延トランザクションを利用するのとできる限り伝票単位ではなく明細単位で更新するのが望ましいと思います。

  • nkmt

    ISHIJIMAさんありがとうございます。

    売上明細などの入力の際中は、全てメモリワーク上で編集し
    SQL Server上のデータへ書き込みなどしておりません。

    保存する時のバッチ処理でトランザクションを開始し、
    SQL Serverのデータに書込みをしております。
    この場合、遅延トランザクションである必要は無いのでしょうね。

  • ISHIJIMA

    メモリで編集して行っていること自身が問題があると思います。(レコードロック等の回避の為)

    メモリを使用せずに遅延トランザクションで行えばすべて解決すると思います。

    今のままのメモリを使用して伝票形式を行おうとするとデッドロック等の回避を行う羽目になります。

     

  • tanda

    データリポジトリの数値型項目のカラム特性に、「更新形式」というオプションがあります。

    ここのデフォルトは「A=値更新」となっており、下位互換ですが、SQL系列のDBを使う場合は、選択肢に「D=差分更新」というのが使えます。

    これを使うと、複数端末からの同時更新が発生しても整合性が維持されます。

    詳細はマジック社のRIAトレーニング3日間で解説しているのですが、SQLをご使用中でしたら、ぜひこの機能を試されることをお勧めします。

  • nkmt

    いつもお世話になっております。
    アドバイスありがとうございます。

    既存システムの売上伝票入力PG等が
    SQL Serverデータ → メモリW
    メモリWで明細入力 → SQL Serverへ書き戻す
    という作りになっております。

    SQL Serverデータのロックが起きるのは、
    保存バッチタスク突入時だけなのですが。

    遅延トランザクションを使う場合、SQL Serverデータへ
    直接入力、更新などを行う作りになるのだと思っております。

    新規案件で遅延トランザクションも検討したいと思います。

    遅延トランザクションだとデッドロックは生じないのでしょうか?

  • ISHIJIMA

    デットロックはトランザクション等の問題ではなくシステム構造の問題だと思っています。

    商品コード1番と2番

    商品コード2番と1番

    この処理を1つのトランザクション内で行うという事に問題があると思います。

    この構造を改善しない限り問題は発生します。

    遅延の場合はどちらかが途中で失敗してロールバックされて整合が保たれるという事だと思っています。

    その整合を保つ処理を自分で考えて処理を作らなければならないのではないかと

    違っていたらすみません。

  • nkmt

    tandaさん、ISHIJIMAさん ありがとうございます。

    SQL系DBの数値型項目の更新形式
    「A=値更新」、「D=差分更新」のご紹介ありがとうございます。
    いまだ試した事がありませんが試してみます。

    dbMAGIC V8 + Pervasiveの頃ってトランザクション開始とか
    レコードロックが残るとか何も考えずに作っておりました。

    SQL Serverを使い始めてから、なんでレコードロック解除待ちが
    出るか意味もわからず。周りも皆最初はそんな状態でした。

    トランザクション開始、コミットを意識するようになりましたが、
    デッドロックが実際に起きているシーンを沢山お客様から聞いた事もなく、
    最近まであまり意識した事もありませんでした。

    私はバッチ処理は、大抵がP=物理、トランザクション開始 T=タスク前の前
    にしております。そのバッチ処理が終えるまで、レコードロック状態が
    残る訳ですもんね。

    知人は、ほとんどトランザクション開始を P=レコード前の前にしているようでした。

    私の伝票入力処理の作りは、伝票修正時は、
    既存のその売上明細データを10明細とか削除して、
    商品月間情報も売上数量を減して、

    その後、メモリWの内容でSQL Serverへ売上明細をINSERTしているような
    処理にしています。
    同時に商品月間情報も売上数量を加算しています。

    私はタスク前トランザクション開始にしているので、
    複数端末で伝票保存する場合、稀に
    商品月間情報でデッドロックが起きていやしないかと気になる連絡が
    ありました。

    伝票新規登録時の伝票番号採番管理データもレコードロック解除待ち
    になりがちなので、それはトランザクション外に置いて、
    そのレコードロックは解除されるようしております。


    とりあえずまずは伝票保存時
    ・タスク前トランザクションのまま
    ・デッドロックを起こす再現実験をしてみます。

  • nkmt

    お客様のmgerror.logの

    レコードロック解除待ちです.データソース:・・・・をまず確認してみます。

  • nkmt

    1日 10時間位稼働で1日 6,000売上明細行のお客様のmgerror.logを覗いてみました。

    <74482206123556192> 26/06/2020 10:44:21.533 [Error ] - レコードロック解除待ちです.データソース: DATA商品月間, program: 売上伝票入力(一般).保存バッチ.商品月間D連鎖更新. S[連鎖更新]商品月間D

    <266541349524965440> 26/06/2020 10:44:18.636 [Error ] - レコードロック解除待ちです.データソース: DATA商品月間, program: 売上伝票入力(一般).保存バッチ.商品月間D連鎖更新. S[連鎖更新]商品月間D

    といったのが100行ぐらい連続しているのが見つかりました。
    1箇所だけですが。デッドロックしている所だと思われます。

    [連鎖更新]商品月間Dというバッチタスクは、拠点別 商品コード別 年月別 月間集計情報で
    前月残~売上数量等の集計~当月残などを保持しているデータです。

    在庫数を数珠繋ぎ更新しているデータですね。

     

  • ISHIJIMA

    このようなテーブルの構成だと伝票単位の更新ではなく明細毎にしないと問題は発生しますね

    昔は集計ファイル等を持ちましたがSQLになってからは持たなくなりましたね・・・

     

  • nkmt

    ishijimaさんありがとうございます。
    売上数や出荷数の月間集計ファイルを持たぬ場合、例えば年次で開始数を持つとか、そんな作りもありなのでしょうね。
    今までは、販売管理には得意先月間情報、仕入先月間情報、商品月間情報など用意する作りばかりでした。

  • ISHIJIMA

    昔は私も集計テーブルを作成していました。

    ただSQLの場合SQL文でいろいろな事ができるで集計ファイルを作成しなくなりました。

    スピードも問題ないので・・

  • nkmt

    統計の為の集計ファイルという側面も確かにありますが、主の存在意義は残高の保持、残数の保持でしょうね。

  • Pu

    こんにちはPuです

    一旦メモリーワークで入力し、その後実テーブルに書き出すと言う動作は

    遅延トランとほぼ同じ動作ですよ。(データセットが同じ仕組みなので)

    ただ競合の仕組みを自前で組み込まないといけませんが

    遅延トランはそのような仕組みをメモリーワークを使わなくてもできる(内部的にはメモリーワークを使用している)

    遅延トランは競合の仕組みをレコード単位、項目単位と細かな設定がノンプログラミングで出来る

    と言うメリットがある。

    WEBマージアプリを作成する場合、遅延と同じ仕組みが必要になるので

    競合(更新前に他のユーザーが書き換えしていないか確認する必要があるので)

    そういうロジックうを良く組み込みました。

    でわ~でわ~

     

  • nkmt

    Puさん、ありがとうございます。

    WEBなど、
    排他やレコードロックなどが無い場合は
    、呼出し前のそのレコードの更新日時と、
    保存しようとした時のそのデータの現在の更新日時を比べるとか
    更新回数カウントを比べるなど、自前で構築するのでしょうね。

  • nkmt

    Puさん アドバイスありがとうございます。

    遅延トランは全然使った事が無いので、私もやってないといけません。

    昨日のユーザーとは別のユーザーのmgerror.logを見てみました。

    同じ仕入先で仕入伝票を入力し、別な人は1~2ケ月前の仕入伝票などを入力保存
    などとした場合、おそらく仕入先別 年月別 買掛金などを保持するデータで
    デッドロックを起こしていそうなエラーログも見つかりました。


    私の作りは、1枚の伝票を二人同時には編集出来ないので、その点では
    問題はありません。

    伝票新規登録、変更、削除の時に
    ・得意先月間情報
    ・仕入先月間情報
    ・商品月間情報
    これらへの更新時に、バッティングするので
    その部分だけを、WRNモードでオープンするのも有りなのかもしれません。

    ちなみにWRNオープンは全く使っておりません。

    クラサバです。


    バッチ処理でデッドロックが生じないように
    P=物理
    L=レコードロック時
    I=即時
    にすれば、1件処理する都度、ロック情報も消えるのでしょうね。


    メモリWで編集して、保存実行時に一括更新バッチ処理をする作りをよく採用しており
    鑑情報をごっそり変える作りが容易だと思っています。

    でもこれは私の固定概念ですので、また別な作りも優れている点があるでしょうね。

  • tanda

    Pervasiveの物理トランザクションしかなかった頃は、ワークファイルを使って処理する方法を用いていた方が多かったようですが、遅延トランザクション機能がリリースされてからは、ほかの皆さんも言われているように、遅延自体をワークにするという手法がメジャーになってきました。この方がプログラムの作成も楽ですし、無用のトラブルを避けることもできますよ。

  • nkmt

    tandaさんありがとうございます。

    クラサバですが新規の分は遅延トランザクションも検討します。

    入力済の伝票を呼び出して、明細を数行削除して、数行追加。
    トランザクション終わる時に、
    それらの更新作業がいっきに物理トランのように動く訳ですもんね。

    私がやってるメモリW編集方式では、1明細の変更であっても、
    伝票修正保存時、既存明細を全部消して、
    メモリWの全レコードを実データへINSERTしている作りにしています。
    負荷は大きいと言えますね。

    明細レコードには、商品コード+日付といったインデックスも用意してありますし。

    遅延トランを用いて鑑は変数+明細は実データとか、鑑も実データとか
    もありなのでしょうね。

    社内にあるので、某RIAソフト、某PKGも参考にしたいと思います。

  • nkmt

    今までは既存レコードを「変更」で開いたと同時に伝票排他情報を作るようにしておりました。

    (入力時ロックは使用しておらず、作りこんでおりました。マスタメンテ等は入力時ロック。)

    それは無しにして、とりあえず照会モードで伝票を閲覧。ファンクションキーで修正モードへ。

    Lock情報を作り、誰がLockしているかわかるよう、伝票毎に編集者ログも記録する

    なんて事を次期目指したいと思います。

  • nkmt

    メモリW編集 物理トランの場合、
    保存を指示してからデータベース更新処理を稼働させる。

    遅延トランの場合、明細入力しながら(実際に物理データに書き込みはしないが)
    物理データへの更新処理を実施する。

    遅延トランで、その伝票への一切の変更を止めたい!
    という時は、Rollbackさせるのでしょうね。多分。

    MSJさんの遅延トランザクションの資料も拝見したいと思います。

     

    あるRIAのソフトを拝見しましたが
    明細メモリWから
    明細実データへバッチ書込みをしておりました。

    伝票修正時は、事前に明細実データをDELETEを済ませるようでした。

    ちょっと思っていた遅延トランの作りとは違っていました。


    売上明細の入力中も
    売上明細のバッチ実データへのINSERT時も
    在庫データへの更新もしていませんでした。


    在庫データは、毎月更新をして、本日理論在庫を求める時は
    前月残+SUM(当月入庫数)-SUM(当月出庫数)のSQL実行
    といった作りがベターなんですかね。

  • nkmt

    商品検索画面に、在庫数も一緒に表示してくれといった需要もありますし。
    遅延トランの時は、1明細入力したら、商品コード+倉庫+年月の集計データを
    更新するのも有りなんでしょうね。

  • nkmt

    某クラサバ販売管理PKGもメモリWで編集して、伝票修正時は
    実データを全DELETEして、商品月間情報減して、数珠繋ぎ更新をし、
    メモリWで実データへ全INSERTして、商品月間情報へ加算、
    数珠つなぎ更新をしていました。

    また参考になる物を探してみたいと思います。

    というかこれ以上は持っていないと思うので、試行錯誤してみたいと思います。

  • tanda

    見たわけではありませんが、今出ているパッケージ商品群はトランザクション処理がメジャーになっていると思いますよ。

    昔のdbMAGICの頃の商品群は、COBOLの手法がそのまま使われているものが多かったように思います。

  • nkmt

    tandaさん、そうでしょうね。
    ちなみに某RIAは、xpa3.1を想定した分で、2016年7月版でした。

    某販売管理は大手老舗PKGで2018年7月版でした。

    ↑追記)これはxpa3.2でした。

  • tanda

    そうですね、dbMAGICの頃からのコンバージョンが多いみたいです。

  • tanda

    PuさんやISHIJIMAさんが推奨されているような、合理的なトランザクションを組み込んだパッケージは、まだまだ少ないのかもしれませんね。

  • tanda

    そういった意味でも、マジック社主催の「RIAトレーニング3日間」は、遅延トランザクションの解説に大幅なページを割いた、最新のテクノロジ提供媒体だと思います。

  • tanda

    ちなみに、私の連載でも書いていますが、遅延トランザクションはWebClientでも完璧に動作します。これを検証したときは感動ものでした!

  • Pu

    こんにちはPuです。

    nkmtさん、なにか話の根幹がずれて来てるような

    前も遅延トラン(magicの世界の言葉:一般的には楽観的ロック)の話がありました。

    データベースのロックを出来るだけ発生させない仕組みですよ。

    webの世界では画面を開きっぱなし、かつ大量のユーザーがアクセスするので

    従来のようなトランザクションロックではロックされる確率が高いので

    楽観的ロックと言う手法が出てきたのです。

    業務上悲観的ロックも必要な場合もありますので。

    でわ~でわ~

     

  • nkmt

    Puさん、tandaさん、ISHIJIMAさん お世話になっております。
    遅延トランの話は前も頂きました。
    まだ使うに至っておりません。
    申し訳ないです。

    私のメモリWで編集して、いっきに実データへ書き込むのも
    出来るだけロック時間を短くするという方式ではあるんでしょうけど
    1明細の変更でも、複数行分のデータの書き込みをするので
    勿体ない伝票入力処理かもなというのを認識しました。


    物理トラン、タスク前トランザクション開始、R=復旧の
    バッチで、デッドロックが起きる実験をしました。
    オンラインタスクを並行実行で2本実行。(別コンテキスト)

    そこからそれぞれ以下のバッチ更新処理を実行。
    片や 担当者マスタを1番、2番、3番~100番まで昇順呼出しで書き換え。
    片や 担当者マスタを100番、99番、98番~1番まで降順呼出しで書き換え。
    どちらも画面で分かり易いよに、レコード毎に1秒のDelayをいれました。

    更新バッチをラインモードで画面に表示。
    途中で両者がデッドロックになるのがよくわかりました。
    同じタイミングで実行すれば、50番前後でデッドロックが生じました。

    こんなにちゃんと再現実験をしたのは初めてでした。

    物理トラン、タスク前トランザクション開始、R=復旧
    またそのタスクが1からリランするのも体験出来ました。
    しかしデッドロックが生じると、
    両者のバッチが最初からやり直しになり、永遠に終わらないのも確認しました。

    R=復旧 はほとんど使った事がありません。

    ISHIJIMAさんも最初提示して頂きましたが
    タスク前トランザクション開始 ではなく
    レコード毎のトランザクションにした所、デッドロックは回避出来ました。


    私はバッチ処理は
    物理トラン、タスク前トランザクション開始、A=アボートにする事が
    多かったのですが、それらは物によっては、レコード毎ロックに
    した方がいい物もありそうです。

サインインしてコメントを残してください。