DOBON.NET DOBON.NETプログラミング掲示板過去ログ

Sqldependencyクラスについて

環境/言語:[WindowsXP/VB.NET 2005]
分類:[.NET]

VB.NET 2005のSqldependencyで
SQLServerのあるテーブル更新を監視しようとします。

---------------------------------------------------
TableaAに下記のような更新をした場合、
Insert into TableA (AAA,BBB) Values (5, 6);
Update TableA Set AAA=1 where BBB=2;

SqldependencyクラスのOnChangeイベントで、
Insert、Updateとも拾えますが。
---------------------------------------------------

ただし、
---------------------------------------------------
TableaAにUPDATEの後でINSERTの場合、
Update TableA Set AAA=1 where BBB=2;
Insert into TableA (AAA,BBB) Values (5, 6);

OnChangeイベントで後ろのINSERTを拾えずに、UPDATE一回しか拾えません。
---------------------------------------------------

同じように、UpdateとDeleteで更新した場合、
先にUpdateの時、DELETEを拾えずに、UPDATE一回しか拾えません。

どうしてこんなことになってしまうか、
教えて頂きたいと思います。
■No25141に返信(agloomyrocさんの記事)
> VB.NET 2005のSqldependencyで
> SQLServerのあるテーブル更新を監視しようとします。

  それらSQL文の実行は、ManagementStudioのクエリの
  実行(T-SQL)で行われたのでしょうか?

  連続して実行された場合、拾えません。

  プログラム的にSqlCommandとして実行された場合も、SQL
  文の実行間隔がイベント処理分空いていれば、拾えます。

  また、Update文で対象となるレコード件数が多い場合も、
  全て拾えるかは何とも言えません。トランザクション処理
  が為されていて、次のSQL文の実行まで時間があれば、
  拾えるかもしれません。

  何が何でも、SqlDependencyで全て拾える・・・と言う前提
  で監視を行うのは無理です。

  あくまで変化があった・・・と見るべきで、SQL文の実行
  間隔によっては、イベントの際、返されるデータ(レコード)
  を真に受けず、再度、SQL文を発行して変化を取得しなお
  す必要があるかもです。

  ただし、SQL Serverが搭載されているPC・サーバーに余計
  な負荷をかけてしまう・・・またロックが発生してしまう場
  合もありますので、注意が必要です。

  変化を発生させるSQL文の実行と監視を行う側とで、何等
  かの調整(細工)が必要です。私は、監視がうまく動作する
  ように更新系のSQL文の発行には細工してます。

※ 日に100万トランザクション以下の処理をさせているシステム
  がありますが、SqlDependencyで監視させていて、月に1回〜
  数ケ月に1回、取れない事象を確認しています。
  うまく調整しても、致し方ない(取れない場合がある)と言
  う前提でシステムがうまく動作する方法を考案して下さい。

  サーバーの性能は、ちょっと公開できませんが、十分に高速
  なマシンでメモリも十分に搭載しています。
  DBサイズは・・・現在約2GB程度(年1GB増加)
  テーブル数は、4テーブルでフィールド数は、平均200以上あ
  ります・・・

  逆に言うと、調整しないで行った場合、ほぼ全く取れません。
  取りこぼしの山です・・・

※ それと2年稼働していますが、1度SqlDependencyでの監視で
  最近に1度内部的エラー(.NETのコア内で)で異常終了しま
  した。どういう事象で落ちたかは解りませんでした。

※ 生産ラインで稼働しており24時間稼働させっぱなしでです。

以上。参考まで
■No25145に返信(オショウさんの記事)

オショウさん、詳しいご説明ありがとうございました。

>   それらSQL文の実行は、ManagementStudioのクエリの
>   実行(T-SQL)で行われたのでしょうか?
>
>   連続して実行された場合、拾えません。
確かにそうです。

VB.NETのソースの中でも試してみましたが、UPDATEして
処理を1秒停止すると、次の更新イベントがちゃんと拾えます。

ご説明の自分の試したことによって、
このクラスに頼ってサーバを監視することかなり危ないと重い、
このクラスを使用することをやめました。

※しかし、上で記述したようにSQLServerの更新を監視したいので、
 何か良い方法がありませんか?

サイヤクの場合は、タイマーをまわし、自分でSQL文を発行して、
更新を検知すると考えています。
あくまでこれは最後の手段です(--;)

是非、ご教授をお願いします。
> ※しかし、上で記述したようにSQLServerの更新を監視したいので、
>  何か良い方法がありませんか?
>
> サイヤクの場合は、タイマーをまわし、自分でSQL文を発行して、
> 更新を検知すると考えています。
> あくまでこれは最後の手段です(--;)

  私は、Insert とUpdateが発生するタイミングが、重ならない
  かどうか(連続して発生しないか?)と、DBやテーブルの構造
  上、連続して発生しにくい構造を考え、SqlDependencyで監視
  するのを2年継続稼働させていますが、前述した通り、事故率
  は、結構無いに等しい・・・

  タイマーで回すよりも、監視クラスとDBへのデータアクセス
  クラスをうまく結合させ、Insert/Update/Deleteが連続して
  発生する場合、ReadWriteLock等使って待ち合わせさせてます。

  まぁ〜DBの構造に結構依存しますので、可能か不可能かは何
  とも言えません。が、考慮すれば限りなく有用な機能になる
  はずです。

  SQL CLR使えば、ストアドを.NETで書けるし、ストアド中から
  イベントも発生させれるので、SqlDependencyの監視モレを補
  間することも可能かと・・・

  やり方は何もひとつでは無いので、適切な方法を模索してみて
  下さい。

  そういうこともプログラマーにとっての醍醐味かと!

以上。
■No25147に返信(オショウさんの記事)
>   私は、Insert とUpdateが発生するタイミングが、重ならない
>   かどうか(連続して発生しないか?)と、DBやテーブルの構造
>   上、連続して発生しにくい構造を考え、SqlDependencyで監視
>   するのを2年継続稼働させていますが、前述した通り、事故率
>   は、結構無いに等しい・・・


早速のアドバイスありがとうございます。

ReadWriteLock、SQL CLRについても調べてみます。

またよろしくお願いします。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板