Mr.Tの場所

特攻野郎Aチームじゃないよー

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  206  : 記事  0  : コメント  838  : トラックバック  43

ニュース

  • 性別:男
  • 猫1:まる
  • 猫2:もろ
  • 猫3:にゃん左部郎
  • タバコ:男は黙ってJPS
[わんくま同盟] C#, VB.NET 掲示板
フィードメーター - Mr.Tの場所

書庫

日記カテゴリ

Mr.Tです、こんにちは。

前回(http://blogs.wankuma.com/mrt/archive/2007/10/12/101615.aspx)の続きです。

 

トランザクションは、一連の流れにある複数の処理をまとめて管理するわけで、最終的な結果が、成功か
失敗かで、一貫性を保つことができます。

じゃあ、具体的に、データ更新中にアクセスしたら、どうなるん?というのは、やはり皆さん知ってるとは思います。
それを具体的にチョー簡単に、試してみましょう。

 

まずは、クエリのウィンドウ(Aとします)を開いて、次のようにSelect実行してみました。

20071013001

 

これに対して、もう一つクエリのウィンドウ(Bとします)を追加してみます。

追加したら、トランザクションをかけて、Update文を書き、その結果を見てみます。

20071013002

 

きちんと更新されています。この状態のまま、ウィンドウAに戻り、再度Selectを実行してみます。

 20071013003

 

さて、何も出てきません。どーなってんの?なんで?とか、最初は思いますが、

この状態では、いくら待っても表示が出てこないので、あきらめてクエリのキャンセルをします。

どうして出てこないのか?それの答えは、ロックにあります。

ロックは、Lockです。鍵のロックと同じですね。

 

SET TRANSACTION ISOLATION LEVEL:

http://msdn2.microsoft.com/ja-jp/library/ms173763.aspx

READ COMMITTED

他のトランザクションで変更されたが、まだコミットされていないデータを、ステートメントで読み取れないように指定します。これにより、ダーティ リードを防ぐことができます。現在のトランザクション内にある各ステートメント間では、他のトランザクションによるデータの変更が可能です。この結果、反復不能読み取りやファントム データが発生することがあります。これは SQL Server の既定のオプションです。

※引用中の赤色は、私がつけたもので、原文は黒色です。

きちんと書いてありますね。コミットされていないデータを読み取るのは、既定でできないようになっています。

20071013004

 

利用状況モニタで見ると、プロセスIDの53番が、55番をブロックしていることがわかります。ちなみに、LCK_M_Sというのは共有ロックを
示しています。(共有ロックってどんなん?ってのはここじゃ触れません)

とりあえず、ブロックしてるよ、というのがきちんとわかればいいわけですね。

決して、SQLServerが壊れたわけではないのです。

 

でも、読み取れるようにしたいのが人情。まあ、変更されたデータでなくとも、変更前の状態でもいいや、となれば
SQLSrever2005では、スナップショット分離というのができるようになっています。

スナップショットとは、ここでは、その時の状態を保存する、くらいの意味ですね。

 

いったんウィンドウBで、前の文をコメントアウトして、Rollback Tranしてください。

で、次のようにします。

20071013005

 

 最初に、スナップショット分離レベルでやるよー宣言してから、トランザクションをかけます。

 

で、ウィンドウAで、スナップショット分離でみるよーと指定して、再度Selectを実行してやると、

 20071013006

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

きちんと、表示できました。

で、ウィンドウBで、再度、全文コメントアウトしてから、RollBack tranしてください。

 

実は、もう一つ方法があります。トランザクションは、そのセッション中でトークン(鍵のようなものですね)を持っていて、そのトークンを

知ることで、トランザクションに参加することが出来ます。

ただし、この方法は、推奨されていません。

http://technet.microsoft.com/ja-jp/library/ms174403.aspx

この機能は、Microsoft SQL Server の将来のバージョンで削除されます。新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションは修正することを検討してください。代わりに、複数のアクティブな結果セット (MARS) または分散トランザクションを使用してください。詳細については、「複数のアクティブな結果セット (MARS) の使用」または「分散トランザクション (データベース エンジン)」を参照してください。

削除されます、と書いてあるくらいに強いわけなので、参考程度ですね。SQLServer2000でも利用はできるはずです。

20071013007

 

最初のSelectで表示された、MCE...という文字列をコピーして、ウィンドウAに次のようにして指定します。

20071013008

 

はい、同じようにできましたね。

 

最後に、プログラムで複数のアクセスがあった場合には、さっきみたいにロックされているとずっと待ってしまうのか?
という点ですが、ADOなどを使う時は、特に指定しないならば、CommandTimeoutでタイムアウトして制御を戻してくれます。

そのため、プログラムがフリーズ状態になってしまう、という現象にはなりません。

#トランザクションがかかっているなら、ちょっと待ってリトライしようよ、ということをしたくなるのですが...

投稿日時 : 2007年10月14日 2:42

コメント

# re: ちょー基本で簡単に、SQLServerでトランザクションの効果を確認する2 2007/10/14 2:49 けろ
あれ?SQL Server 2005 のデフォルトトランザクションレベルって、READ COMMITTED でしたっけ?
(begin tran した時にトランザクションレベルをつけてなかったので、省略するとどうなるんだっけかな?って思いましたです)

トランザクションレベルを明示的につけたサンプルの方が、わかりやすかったかなと思いました。(あくまで、個人的な勝手な意見ですいません)


# re: ちょー基本で簡単に、SQLServerでトランザクションの効果を確認する2 2007/10/14 3:12 Mr.T
つっこみ、ありがとうございます。
MSDSに間違いなければ、既定はRead Commitedです。

>トランザクションレベルを明示的につけたサンプルの方が、わかりやすかったかなと思いました。
あー、そういやそうですねぇ。
トランザクションレベルってナニ?ってレベルくらいの話と思ってもらえるとありがたいです。
へー、Read Commitedっていうのがあるんだー、
既定だとよめないんだー、
というのを「実感」してほしいな、と思った次第で。

他にも間違い、勘違い、適当などありましたら遠慮なくお願いします。

#あ、そういや最後のリトライの処理とか
#けろさん...エントリでやってもらえたりなんかしちゃうことありません?
#とかいってみたりするwww

# re: ちょー基本で簡単に、SQLServerでトランザクションの効果を確認する2 2007/10/14 12:50 けろ
あ、やっぱり。(既定はRead Commited)
それなら、このサンプルでOKですね。

>あ、そういや最後のリトライの処理とか
>けろさん...エントリでやってもらえたりなんかしちゃうことありません?

ぜひ、Mr.Tさんに差し上げますと言ってみるテストw
でも、おもしろそうですね。ちょっとネタにしてみたい気分ですw


# re: ちょー基本で簡単に、SQLServerでトランザクションの効果を確認する2 2007/10/14 13:11 けろ
それから、SnapShotですが、経験上、レスポンスが悪くて話になりませんでした。
(tempdbに同期データを格納するので)
中さんのアドバイスでtempdbのファイル分割等をやってだいぶ良くなったんですけどね。

UPDATEで、ロックの問題を避けるために、SnapShotは安全かなと思いますが、SELECTで使うときは、レスポンスや処理・用途に応じたトランザクションレベルを適切に設定すべきなんでしょうね。
(全部SnapShotにすればいいかというと、私の個人的な意見ではNOですね)

# sp_bindsession は、将来のバージョンでなくなってしまうのは、知りませんでした orz
  使うのを自粛しないといけませんね。勉強になりました。


# re: ちょー基本で簡単に、SQLServerでトランザクションの効果を確認する2 2007/10/14 14:51 Mr.T
>それから、SnapShotですが、経験上、レスポンスが悪くて話になりませんでした。
なるほど、tempdbにデータ格納するのは聞きかじってましたが、レスポンスは良くないわけですね。

やはり全部Snapshotにするのは私も意味がないとは思いますが、そうなると使いどころで、具体的にどういうケースがよいのかが問題になりますね。

>ぜひ、Mr.Tさんに差し上げますと言ってみるテストw
自分がやると、ちょー適当になりそうな予感と悪寒www
...いや、逆に考えたら、即効突っ込んでもらえて幸せ状態になれるのか?

# re: ちょー基本で簡単に、SQLServerでトランザクションの効果を確認する2 2007/10/15 0:50 けろ
>自分がやると、ちょー適当になりそうな予感と悪寒www

ぜひ、Mr.Tさんにやって頂きたいですね。
いい加減でもいいので、徐々に反応をみながら、修正するっていうのも、
おもしろいかもしれませんよ!

Post Feedback

タイトル
名前
Url:
コメント