(現在 過去ログ36 を表示中)

HOME HELP 新規作成 新着記事 トピック表示 ファイル一覧 検索 過去ログ

[ 最新記事及び返信フォームをトピックトップへ ]

■5188 / inTopicNo.1)  外部dbでのロック
  
□投稿者/ 尾形 -(2009/09/29(Tue) 17:42:57)
    何度もすいません。またよろしくお願いします

    自分は年度別に伝票番号をつけています
    主キー(id)とは別に管理したいと思っています

    伝票番号を管理するテーブルから番号を+1して
    取得しようとする処理を考えた場合に困ってしまいました
    今のこの値は最新なのか? 
    値を信用できないので大変です

    「ロック」コマンドは外部DBで使えないですよね
    「トランザクション」でのみロックを制御できるように思いました
    ロックしたい行に架空のデータを書き込みして(ロック掛けて)
    別クエリーで最新を引いてくればいいかなと思っています
    (再抽出ではダメ)


    トランザクション 開始
    結合  "伝番ロック用.XVW",,表番号=1
    代入  &最大値=#乱数(32767)
    行訂正 終了状態=&秒,[work]=&最大値
    結合  "伝番更新用.XVW",,表番号=2
    行訂正 [伝番]=[伝番]+1
    代入  &伝番=[伝番]
    編集表 1
    行訂正 [work]=""
    トランザクション コミット


    なんか気に入らないのですが
    ロックをスマートに掛ける良い方法ってないのでしょうか

引用返信 [メール受信/OFF] 削除キー/
■5189 / inTopicNo.2)  Re[1]: 外部dbでのロック
□投稿者/ うにん -(2009/09/30(Wed) 09:14:21)
    > 自分は年度別に伝票番号をつけています
    > 主キー(id)とは別に管理したいと思っています

    ロックの方法ではないですが、オートナンバーを年度初めにリセットするのではだめなんですか?

    リセット不可能なら例えば
    [通番]オートナンバー
    [年度]整数
    [初期値]長整数
    で今年度の行がなければ[初期値]を[通番]に設定
    [通番]-[初期値]を使うとか。
引用返信 [メール受信/OFF] 削除キー/
■5190 / inTopicNo.3)  Re[1]: 外部dbでのロック
□投稿者/ hidetake -(2009/09/30(Wed) 13:18:25)
    2009/09/30(Wed) 13:27:36 編集(投稿者)

    > 「トランザクション」でのみロックを制御できるように思いました

    何故に「外部DB」で「トランザクション」が有効に働くと
    思われたのかな?


    さて、
    > 今のこの値は最新なのか? 
    > 値を信用できないので大変です
    新規に追加したい番号を取得したいのなら、シーケンスに
    設定した id に自分がこれからデータを追加するよと
    データを追加し(この追加の際に)自分を特定できる情報と
    今回の書き込みの情報も埋め込んで置いて、サーバ側に
    id は付けてもらい、そのデータを取ってくれば、自分用
    の id が得られるのでは?

    実際の伝票の追加が(編集の)途中で破棄される(事が多い)
    のならば、伝票をまず仕立てておいて、実際に書き込む際
    に自分用の番号を取ってくるとか。

    流れで言うと

    サーバで
    ---------------------------
    CREATE TABLE "DENBAN" (
    id serial8 primary key,
    userid text);
    ---------------------------
    のテーブルを用意。

    クライアントには自分のデータを書き出しするための
    テーブルとしてワークテーブルを用意
    denban.tbl
    [id]
    [userid]
    このテーブルには、外部DB書き出しする条件を登録。
    条件は、テーブル名 DENBAN、書き出し項目 [userid]、
    書き出しは「追加」で指定。
    # PostgreSQL は大文字のテーブル名で無いと追加
    # できないので DENBAN とした。

    最新の自分用の id 取得用に "denbanget.xvw" を
    作成し、id と userid を設定。 userid の抽出条件に
    パラメータ変数 &userid を設定し、この条件にあう
    ものだけを抽出するようにする。

    あとは
    --------------------------------------------
    変数宣言 整数{&hODBC,&Ret} \
    ,文字列{&userid}

    外部DB 接続,ODBC="hoge" \
    ,ユーザ名=""\
    ,パスワード="" \
    ,接続ハンドル=&hODBC \
    ,終了状態=&Ret

    表 "denban.tbl"
    行削除 *,圧縮,終了状態=&Ret

    &userid=#WSNAME+"-"+#ユーザ名+"-"+#日時文字列(#日時値,11,4,2)

    行追加 終了状態=&Ret \
    ,[userid]=&userid

    書き出し 外部DB \
    ,条件名="denbanset" \
    ,引継ぎ=する \
    ,終了状態=&Ret
    終了 表 編集対象表

    結合 "denbanget.xvw" \
    , \
    ,変数使用=する \
    ,終了状態=&Ret

    確認 #str([id])

    外部DB 切断 \
    ,&hODBC \
    ,終了状態=&Ret
    --------------------------------------------
    てな具合に。(細かいことは抜きで)


引用返信 [メール受信/OFF] 削除キー/
■5194 / inTopicNo.4)  Re[2]: 外部dbでのロック
□投稿者/ 尾形 -(2009/09/30(Wed) 18:42:08)
    どうも、ありがとうございます

    > 何故に「外部DB」で「トランザクション」が有効に働くと
    > 思われたのかな?
    pc1側でトランザクション開始してから
    「伝番管理」テーブルを行訂正して
    メッセージボックスを出して放置(未コミット状態)
    その状態でpc2側で行訂正しようとしてもできなかったからです

    いくつか方法がある事は分かりました
    自分なりに考えてみます


    (あまりにも連投しているので気がひけています m(__)m )
    気が向いたらアドバイス下さい
    伝票ヘッダに[直納先id]の項目があります
    値を入力する時もあればしない時もあります
    今まではフォーム上で#表引き関数で直納先名は表示していました
    外部dbに対しては#表引き使えないと思います
    そのため、伝票ヘッダと直納先マスタを結合指定しようと思います

    でも結合すると、[直納先id]が入力されている分しか伝票が表示
    されなくなりました
    ALL指定(全レコード抽出指定)すると実表更新が出来なくなります
    こういう場合、[直納先id]はnot NULL 制約にして必ず何か入力
    させるようにするしかないのでしょうか
    (という事は#表引きさせたいような項目は全てnot NULL ?)

引用返信 [メール受信/OFF] 削除キー/
■5195 / inTopicNo.5)  Re[3]: 外部dbでのロック
□投稿者/ hidetake -(2009/09/30(Wed) 18:48:13)
    >>何故に「外部DB」で「トランザクション」が有効に働くと
    >>思われたのかな?
    > pc1側でトランザクション開始してから
    > 「伝番管理」テーブルを行訂正して
    > メッセージボックスを出して放置(未コミット状態)
    > その状態でpc2側で行訂正しようとしてもできなかったからです

    それって、伝番ロック用.XVW を専有で開いているから?
    別のところにある 伝番ロック用.XVW を開いた?

    自分が書いたやつでも denban.tbl は共有は考えて無く
    クライアントにある自分専用のテーブルのつもりで!


引用返信 [メール受信/OFF] 削除キー/
■5196 / inTopicNo.6)  Re[4]: 外部dbでのロック
□投稿者/ 尾形 -(2009/09/30(Wed) 18:58:45)
    > 別のところにある 伝番ロック用.XVW を開いた?
    それぞれのpcローカル側に伝番ロック用.XVWを置いて
    やってみました
    pc2側でも伝番ロック用.XVWは開けました
    行訂正して表示モードに戻そうとしたら
    待たされてからはじかれました
    待っている間に、pc1側でメッセージボックスを
    解除してコミットするとpc2側は進みました


引用返信 [メール受信/OFF] 削除キー/
■5199 / inTopicNo.7)  Re[5]: 外部dbでのロック
□投稿者/ hidetake -(2009/09/30(Wed) 20:14:12)
    2009/09/30(Wed) 20:20:21 編集(投稿者)

    >>別のところにある 伝番ロック用.XVW を開いた?
    > それぞれのpcローカル側に伝番ロック用.XVWを置いて
    > やってみました
    > pc2側でも伝番ロック用.XVWは開けました
    > 行訂正して表示モードに戻そうとしたら
    > 待たされてからはじかれました
    > 待っている間に、pc1側でメッセージボックスを
    > 解除してコミットするとpc2側は進みました

    「ロールバック」すると外部DBのデータはどうなる
    のでしょうか?
    # 桐だけの事を想定するか、それ以外の更新を考慮する
    # とか(今後のために)しないとかあると思いますけど。

引用返信 [メール受信/OFF] 削除キー/
■5202 / inTopicNo.8)  Re[3]: 外部dbでのロック
□投稿者/ hidetake -(2009/09/30(Wed) 21:52:25)
    > #表引き

    表引きしなければならないマスターはどのぐらいの頻度で
    更新されるのですか?

    1日のうちで何度も? マスターだからそんなには無い?
    とかで変わってくるかと思いますが、更新頻度が少ないの
    ならば、1日1回朝一番で外部DBからローカル(もしくは共有)
    のテーブルに最新データを落としてくるとか、更新頻度が
    1日内であるのは、最終更新日時を元に、表引きすべき時
    に更新日時をチェックし、データ件数によっては、全体を
    引っ張ってくるとか、更新されたものだけを更新するとか?
    # あるいは誰かがマスターを更新するのだから、更新が
    # 発生した際に、ローカル(あるいは共有)のマスターも
    # 更新するとか!?

    あるいは、その都度、マスターなる外部DBを表示させ
    選択させるとか?  一覧表示させないのなら、その値で
    データだけを取ってくる外部DBなり仕組みを作るとか・・・
    # レスポンス等の問題なども考慮のうえ

    まぁ〜、その実体によって工夫するしか無いのかなとか?

    わかってもらえるかな!? (^^;

引用返信 [メール受信/OFF] 削除キー/
■5204 / inTopicNo.9)  Re[4]: 外部dbでのロック
□投稿者/ 尾形 -(2009/09/30(Wed) 22:41:07)
    どうも、すいません

    > わかってもらえるかな!?
    大体分かりました
    なんか、桐だけ(外部db使ってない)の時と同じ苦労が (^^;

    マスタは2万程あります
    vpn経由の処理も考えていますので
    都度確保はちょっと厳しいかも

    ちなみにアクセスの場合ってどうなるのですか
    このあたりは同じじゃないのでしょうか

    #単票形式ならプログラム側で持ってきてもいいと思うけど
    #ある程度の行数の一覧形式だとどうするのでしょうか

引用返信 [メール受信/OFF] 削除キー/
■5207 / inTopicNo.10)  Re[5]: 外部dbでのロック
□投稿者/ hidetake -(2009/09/30(Wed) 22:55:35)
    > マスタは2万程あります
    > vpn経由の処理も考えていますので
    > 都度確保はちょっと厳しいかも

    2万行って、表引きで引っ張ってこないといけない内容は?
    2万行って全部を最初から無謀で、その段階のマスターとか
    無いの? 条件に応じたデータだけを表示させるワケには
    いかないのかな?

    まぁ〜外部DBはいろいろあるでしょうから、ご検討をお祈り
    致します! _o_

引用返信 [メール受信/OFF] 削除キー/
■5209 / inTopicNo.11)  Re[6]: 外部dbでのロック
□投稿者/ 尾形 -(2009/10/01(Thu) 07:49:51)
    どうも、すいませんでした

    上手く伝え切れなかった部分もありましたようで
    どうか気を悪くされないでください
    すいませんでした m(__)m

    # #表引き の代わりは結合でnot NULLでやってみます
    # 新規行追加時は相手名が表示されない(再抽出まで)ので
    # イベントでダミー項目にでも書き込む方向で考えてみます

    しばらく自主規制します (^^;

引用返信 [メール受信/OFF] 削除キー/
■5210 / inTopicNo.12)  Re[7]: 外部dbでのロック
□投稿者/ hidetake -(2009/10/01(Thu) 08:00:25)
    2009/10/01(Thu) 08:11:07 編集(投稿者)

    > どうも、すいませんでした
    > 上手く伝え切れなかった部分もありましたようで
    > どうか気を悪くされないでください
    > すいませんでした m(__)m
    > しばらく自主規制します (^^;

    これって、私に!?

    気を悪くするも何も、一緒に学んだり向上する気のある人には
    協力しますよ。でも、いつも答える(えられる)とは限りません
    けど。 (^^)

    今回、自分も知らなかったことも学べたし・・・

    桐で外部DBを使い出すと桐側で出来ることも限られているので、
    サーバ側でトリガ使ったり、いろいろ工夫する必要も出て来る
    と思います。と言うことで、がんばって下さい。

    # 桐の外部DB で、12万件の単純全抽出で 5秒の MySQL って
    # 自分も結構気になってはいます(しかも InnoDB で)。
    # PostgreSQL はもっと遅いですし。データ転送容量は別と
    # して 2万件レベルから必要なものだけを持ってくるのには
    # MySQL だと抽出しテーブル化するのにどれだけの時間が
    # かかるのか? とか、テーブル化しなくとも別ウィンドウ
    # で表示・選択させる方式とかスピードの力でどうかなとか
    # 面白そうではあります。

引用返信 [メール受信/OFF] 削除キー/
■5211 / inTopicNo.13)  Re[8]: 外部dbでのロック
□投稿者/ 尾形 -(2009/10/01(Thu) 09:17:08)
    そう言って頂けるとうれしいです

    ADSLのVPN超えで50万程度の明細から
    500行程まで抽出で十分実用的な感じがしました
    絞込項目は主キー指定

    明細量は索引さえあれば量は無関係な気がしました
    抽出量をいかに少なく絞るかだと思いました


    では、またよろしくお願いします

引用返信 [メール受信/OFF] 削除キー/
■5213 / inTopicNo.14)  Re[9]: 外部dbでのロック
□投稿者/ 今村 誠 -(2009/10/01(Thu) 11:35:26)
    尾形さんこんにちは
    > ADSLのVPN超えで50万程度の明細から
    > 500行程まで抽出で十分実用的な感じがしました
    > 絞込項目は主キー指定

    4万行の住所データを作ったのですが、インストールを
    した\mysql\data\rei01\ の下にdenban.frmやogata.frm
    db.optが作成されて桐(26M)に比べて(20K)と極端に差が
    ありますが、他の部分にはデータがあると言うことは
    無いでしょうか。
    xvwは桐のデータフォルダーの中に200K以下でしたが
    これはいつでも接続して作成可能なので、実体は最初の
    (20k)の中に全てあると言うことですか?

    > 明細量は索引さえあれば量は無関係な気がしました
    > 抽出量をいかに少なく絞るかだと思いました

    索引は桐で結合した時にメニューから選べませんでしたが
    mysqlのコマンドで作る必要があるのですか?

    起動と終了のコマンドが面倒になったのでフォームを作り
    イベントで起動と終了をしましたが、例えばテーブル作成や
    項目順番変更やデータ型変更のフォームはあれば便利では
    ないかと思いましたが、何かツールがあるのでしょうか。
引用返信 [メール受信/OFF] 削除キー/
■5214 / inTopicNo.15)  Re[10]: 外部dbでのロック
□投稿者/ 尾形 -(2009/10/01(Thu) 13:17:24)
    http://www.javadrive.jp/mysql/administrator/index.html
    ツールはMySQL Administrator
    ただし、項目の挿入はGUIでは出来ないので
    MySQL Query Browserからコマンドで


    参考になる方がいるかもしれないので
    いくつか感じた点をまとめておきます(違ってたらゴメン)
    MySQLのデータベース種類にはInnoDBやMyISAM 他複数ある
    InnoDBを推奨
    ODBCドライバは5.1よりも3.51が良いみたい
    現状、イベント定義編集画面にはバグがある
    装飾が使えないので項目名はテーブル間で統一化しない方がいい(多分)
    #表引きは使えないので結合で処理する
    (マスタ側idを更新禁止に設定して入力後イベントで名称は引いてくる)
    #DSQLはWHERE句のみしか指定できないが、); を上手く利用すれば
    色々なクエリーが処理できる
    ロックは使えないのでトランザクションを利用する
    1万行程度なら簡単に全行抽出の一覧表形式で共有でも運用できそう
    (ただし排他がかからない)
    PostgreSQLよりMySQLが桐にはいいらしい

    すいません、思いつくまま

引用返信 [メール受信/OFF] 削除キー/
■5215 / inTopicNo.16)  Re[11]: 外部dbでのロック
□投稿者/ 今村 誠 -(2009/10/01(Thu) 15:07:04)
    尾形さんこんにちは
    > http://www.javadrive.jp/mysql/administrator/index.html
    > ツールはMySQL Administrator
    > ただし、項目の挿入はGUIでは出来ないので
    > MySQL Query Browserからコマンドで

    桐で作ったが使い良くできそうですね

    > MySQLのデータベース種類にはInnoDBやMyISAM 他複数ある
    > InnoDBを推奨

    ibdata1というファイルがあり34Mありました。
    標準でコマンドから作るとInnoDBになる様に思いました。
    テーブル名.MYIという拡張子のファイルは存在していない
    ようです。

    > #DSQLはWHERE句のみしか指定できないが、); を上手く利用すれば
    > 色々なクエリーが処理できる

    #DSQLをイベントファイルに書いてみましたがボタンから実行
    したらエラーになりました。(使用できない関数です)
    Proc 伝番取得()
     var 数値 { &denpyou }
     &STR=#dsql("denpyou_cd=(SELECT MAX(denpyou_cd) FROM irainusi)")
    End

    > 1万行程度なら簡単に全行抽出の一覧表形式で共有でも運用できそう
    > (ただし排他がかからない)

    共有が目的なので、都合良いのではないでしょうか。
引用返信 [メール受信/ON] 削除キー/
■5216 / inTopicNo.17)  Re[12]: 外部dbでのロック
□投稿者/ うにん -(2009/10/01(Thu) 16:53:56)
    >>ツールはMySQL Administrator
    >>ただし、項目の挿入はGUIでは出来ないので

    テーブルをダブルクリックするとTable Editorが起動します。

    > #DSQLをイベントファイルに書いてみましたがボタンから実行
    > したらエラーになりました。(使用できない関数です)

    外部DBの絞り込み条件専用の関数です。

引用返信 [メール受信/OFF] 削除キー/
■5217 / inTopicNo.18)  Re[1]: 外部dbでのロック
□投稿者/ うにん -(2009/10/01(Thu) 17:21:21)
    > 伝票番号を管理するテーブルから番号を+1して
    > 取得しようとする処理を考えた場合に困ってしまいました

    SQLでロックしようと思ったら、
    #DSQL("1);SELECT * FROM test2 FOR UPDATE;UPDATE test2 SET denban=denban+(1")
    桐が1回の抽出で#DSQLを含んだSQLを2回実行するので+2されてしまった。
    (1回目はSELECT COUNT(*)〜で行数だけを取得している)

    2からはじめて2で割って使用するか、+0.5にする?

    2回の間に割り込まれるってこともあるのか?タイミングが微妙すぎて再現できそうにない。
引用返信 [メール受信/OFF] 削除キー/
■5219 / inTopicNo.19)  Re[2]: 外部dbでのロック
□投稿者/ hidetake -(2009/10/02(Fri) 10:47:04)
    > FOR UPDATE

    明示的なトランザクションの開始やコミットをしていない場合、
    FOR UPDATE はどの時点まで有効なのでしょうかね?
    自動コミットはどの時点で働くのか?でしょうけど、
    外部DB 接続で接続を維持している間とかどうなるのだろうか?

    なんて気にかかります。

引用返信 [メール受信/OFF] 削除キー/
■5220 / inTopicNo.20)  Re[3]: 外部dbでのロック
□投稿者/ hidetake -(2009/10/02(Fri) 11:04:21)
    2009/10/02(Fri) 11:10:02 編集(投稿者)

    >>FOR UPDATE

    自分の手元の PostgreSQL 7.2 相手に、絞り込み条件
    #DSQL("id = 20091443) FOR UPDATE;--(")
    で、抽出してみたけど、他の PC からも 即 訂正可能
    でした。(^^;

    PostgreSQL 7.2 では、最初の SELECT COUNT(*) 時の
    FOR UPDATE はエラーを出したけど、次の実際の抽出
    クエリは実行されたのだけれど・・・
    # 最初のエラーは集計に FOR UPDATE が付加された
    # ためで、うにんさんの式とは違うので当然ではあり
    # ます。ただカウント(エラーが発生しても)されなく
    # とも次の実際に必要なクエリは実行されるという事。

    ---------------------------------------------------------------------------
    [5.766]conn=03603A88, query='SELECT COUNT(*) FROM "reikai" WHERE (id = 20091443) FOR UPDATE;--()'
    [5.766]ERROR from backend during send_query: 'ERROR: SELECT FOR UPDATE is not allowed with AGGREGATE'
    [5.766]STATEMENT ERROR: func=SC_execute, desc='(null)', errnum=7, errmsg='Error while executing the query'
    [5.766] ------------------------------------------------------------
    [5.766] hdbc=03603A88, stmt=03608AA8, result=03609D30
    [5.766] prepare=0, internal=0
    [5.766] bindings=00000000, bindings_allocated=0
    [5.766] parameters=00000000, parameters_allocated=0
    [5.766] statement_type=0, statement='SELECT COUNT(*) FROM "reikai" WHERE (id = 20091443) FOR UPDATE;--()'
    [5.766] stmt_with_params='SELECT COUNT(*) FROM "reikai" WHERE (id = 20091443) FOR UPDATE;--()'
    [5.766] data_at_exec=-1, current_exec_param=-1, put_data=0
    [5.766] currTuple=-1, current_col=-1, lobj_fd=-1
    [5.766] maxRows=0, rowset_size=1, keyset_size=0, cursor_type=0, scroll_concurrency=1
    [5.766] cursor_name='SQL_CUR03608AA8'
    [5.766] ----------------QResult Info -------------------------------
    [5.766] fields=03F125F0, backend_tuples=00000000, tupleField=0, conn=00000000
    [5.766] fetch_count=0, num_total_rows=0, num_fields=0, cursor='(NULL)'
    [5.766] message='ERROR: SELECT FOR UPDATE is not allowed with AGGREGATE', command='(NULL)', notice='(NULL)'
    [5.766] status=7, inTuples=0
    [5.766]CONN ERROR: func=SC_execute, desc='(null)', errnum=110, errmsg='ERROR: SELECT FOR UPDATE is not allowed with AGGREGATE'
    [5.766] ------------------------------------------------------------
    [5.766] henv=03603A58, conn=03603A88, status=1, num_stmts=16
    [5.766] sock=036065D0, stmts=036086A8, lobj_type=-999
    [5.766] ---------------- Socket Info -------------------------------
    [5.766] socket=592, reverse=0, errornumber=0, errormsg='(NULL)'
    [5.766] buffer_in=56649368, buffer_out=56653472
    [5.766] buffer_filled_in=1, buffer_filled_out=0, buffer_read_in=1
    [5.797]conn=03603A88, query='SELECT "id","コースNo",・・・,"記入日","更新日","編集日","年度" FROM "reikai" WHERE (id = 20091443) FOR UPDATE;--() ORDER BY "id" ASC '
    [5.859] [ fetched 1 rows ]
    [10.359]conn=03603A88, query='UPDATE "reikai" SET "hogehoge"=NULL WHERE "id"=20091443'
    [10.359]conn=03603A88, query='COMMIT'
    [12.609]conn=03603A88, PGAPI_Disconnect
    ---------------------------------------------------------------------------

引用返信 [メール受信/OFF] 削除キー/

次の20件>

トピック内ページ移動 / << 0 | 1 | 2 >>

[このトピックに返信]
Mode/  Pass/

HOME HELP 新規作成 新着記事 トピック表示 ファイル一覧 検索 過去ログ

- Child Tree -
- Antispam Version -