• 締切済み

ADO接続のトランザクション処理

SQL2005のDBに対して ADOのconnectionオブジェクトで接続しているのですが、 下記のようにトランザクションを開始し、SQLを実行し、 エラーが発生してロールバックを行っていない場合、 2個目のSQLがいつまでたってもロック状態でタイムアウトになりません。 このような場合、ADOconnectionのコマンドタイムアウトのデフォルト値30秒で タイムアウトとなり、ロールバックされないのでしょうか? 以下adoコネクションオブジェクトをConnobjと表記します Connobj.BeginTrans Connobj.Execute "Insert into AAA・・・・" ← このInsert文で失敗 Connobj.Execute "Update BBB SET ・・・・" ← このUpdateは成功 ※ロールバックもコミットも行わない  (プログラムの不具合でロールバックができなかった場合や、  アプリで異常が発生してロールバックが行えない等) お手数をおかけしますが、何かご存知の方、ご教授願います。

みんなの回答

回答No.5

CommitTransなり、RollbackTransを例外処理と組み合わせて使わないとですね。

  • 0909union
  • ベストアンサー率39% (325/818)
回答No.4
  • 0909union
  • ベストアンサー率39% (325/818)
回答No.3

コマンドのエラーで起きるなら、スクリプト行レベルでトラップを掛けるといいでしょう。他の方が提示していますね。 しかし、 >2個目のSQLがいつまでたってもロック状態でタイムアウトになりません >コマンドタイムアウトのデフォルト値30秒でタイムアウトとなり、ロールバックされないのでしょうか の問題であれば、DBMSレベルでトリガーでトラップを掛ける必要があります。 マニュアルや、リファレンスを参照してください。OracleならPL/SQLなどですよね。 また、GUIレベルのプロパティーに、タイムアウトの設定かがあったかと思います。 どちらかを選択することになります。 http://msdn.microsoft.com/ja-jp/library/938d9dz2(v=vs.80).aspx http://msdn.microsoft.com/ja-jp/library/938d9dz2.aspx http://msdn.microsoft.com/ja-jp/library/ms189799.aspx http://www.google.co.jp/search?hl=ja&q=SQLServer+%E3%83%88%E3%83%AA%E3%82%AC%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A&lr=lang_ja いずれにせよ、トリガーなどは自身でトラップに引っかかりやすいので、限定する項目を精査して、設定する必要があります。 (システムのタイムアウトイベントをトリガーとしてするのか、実行からWait時間で取得値の有無でトリガーとするのか、またロールバックが必ずしもよいとはいえない)

sin201102
質問者

お礼

ありがとうございます。 通常、トランザクション処理を行う場合、 教えていただいたトリガー等でロック解除用のものを用意するんでしょうか? ADOかSQLServerのコマンドタイムアウトで ロールバックがかかると思っていたのですが・・・・ 知識が浅く、とんちんかんな質問をしていたら申し訳ないです。

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.2

言語は何をお使いですか? ~VB6、VBAなら Connobj.BeginTrans実行の前に「On Error Goto ラベル」でエラー処理に飛ばして、そこで「Connobj..RollbackTrans」を行えばいいと思うのですが。 VBAなどでは、「On Error Goto ラベル」宣言せずに実行中エラーが発生すると「終了」「デバッグ」のユーザ入力待ちになって固まってしまいます。

sin201102
質問者

お礼

ありがとうございます。 ASPなのでVBAです。 ADOコネクションオブジェクトにセッションスコープを与えて利用しています。 かなり以前に作成されたプログラムで、 最近ロックが残ったままとなる現象が発生し、 調査したところ、トランザクション処理を行っているASPで On Error Goto の記述が抜けており、ロールバックすることが出ていませんでした。 「終了」「デバッグ」のユーザ入力待ちとありますが、 この間もコマンドタイムアウト(SQLSERVER側も?)が発生せずに、 ロックが残ってしまうのでしょうか?

  • marutone
  • ベストアンサー率40% (70/174)
回答No.1

トランザクション開始後のInsert文が失敗した時点で、 try~catch等を使用してエラーハンドリングをし、 ロールバックを行うという方法が正しいです。

sin201102
質問者

お礼

ありがとうございます。 エラー処理が不十分でロールバック処理が行えず Update文のロックが残ったままとなってしまってました。

関連するQ&A

  • ACCESSでのトランザクション処理

    VB6+ACCESS2000で開発をしております。 VBとACCESSとの接続はADOでおこなっております。 ACCESSはそれほど使ったことがないのでよくわからないのですが、ACCESSでトランザクション処理はできるのでしょうか? ロールバックもコミットも見たところありませんでした。 教えてください。

  • 複数のSQL文を一つのトランザクションで行いたい(SQL Server)

    Visual Basic 2005 から SQL Server に接続してINSERTやUPDATE処理を行いたいのですが、トランザクション処理の記述方法が分かりません。 コネクションオープン トランザクション開始  クラスA呼び出し(INSERTやUPDATEの処理記述)  クラスB呼び出し(INSERTやUPDATEの処理記述)  … コミット(またはロールバック) トランザクション終了 コネクションクローズ 上記の様に、いくつかのクラスに分けて記述したINSERTやUPDATEの処理を、一つのトランザクションで行いたいです。 コネクションやトランザクションを引数とすればよいのでしょうか?

  • accessVBAでのワークスペース

    こんばんわ。 今年の四月から新米SEとして働いているものです。 他の言語の場合どうなるかわかりませんが、accessの場合、トランザクションを開始してSQL文を実行する際、「データベース.Execute SQL文」となると思うのですがDAOやADOで接続する際、最初のほうでワークスペースを定義しますよね。 トランザクションの開始、コミットやロールバックは、「ワークスペース.BeginTrans、ワークスペース.CommitTrans、ワークスペース.RollBack」なのになぜSQLを実行するときだけ「データベース.Execute SQL文」なのでしょうか? 私なりの考えでは、ワークスペースは中間作業領域。中間作業領域でなにかしらのエラーが起きたらロールバック、もし問題なければコミットするのでワークスペース.Commit等というのは理解したのですが、SQL文を実行するのはトランザクション中なのでワークスペースで実行「ワークスペース.Execute SQL文」なのではないのでしょうか? ワークスペースへの理解が誤っているのでしょうか? よろしくお願いします。

  • トランザクションとlast_insert_id

    トランザクション中にinsertする予定のテーブル(未コミット)のauto_increment値を取得することはできるのでしょうか。 以下のような処理を期待しているのですが、hoge1テーブルのauto_increment値が取得できずに困っております。last_insert_id に関わらず、hoge1テーブルのauto_increment値が取得できる方法があれば教えてください。 (1) トランザクション開始 (2) $sql=" INSERT INTO hoge1(name) value('あああ'); "; (3) ( ロールバック ) (4) $key=mysql_insert_id(); (5) $sql2=" INSERT INTO hoge2(hoge1_primary,age) value($key,'20歳'); "; (6) ( ロールバック ) (7) コミット (8) トランザクション終了 よろしくお願いします。 環境: php5,mysql5 (InnoDB)

    • ベストアンサー
    • MySQL
  • トランザクションの考え方の疑問点

     トランザクションについてネットでいろいろ調べたのですが、 ピンと来ていないので下記の意味合いで合っているのか、 教えて頂けないでしょうか? ・トランザクションは、データベースに対してかかる (テーブル単位にかかるわけではない) ・SQLでINSERT、UPDATE、DELETEのようにテーブルに更新処理を 走らせた時、そのテーブルがロックされる ・コミットが終わるまではロックはかかったまま ・失敗すればロールバックでデータを元に戻せる  …こんな風に考えていますが、 ここまでは合っているでしょうか? また、下記からが疑問なんですが… ・ロックの種類は、SQLの書き方で決められるみたいですが、 特に指定しなかったらテーブルロックになるものなのでしょうか? ・SELECT中は、ロックがかかるものなのでしょうか?

  • トランザクション処理について

    質問させて下さい。 以下の処理を行なっております。 1. トランザクション処理開始 2. テーブルAからデータをDELETE 3. テーブルBへデータをINSERT 4. トランザクション処理終了 上記処理の場合の「TYPE=InnoDB」指定の仕方が不安です。 現在はロールバックの可能性のあるテーブルAのみ「TYPE=InnoDB」を指定しています。 その状態でコミットもうまくいっているのですが、テーブルBに「TYPE=InnoDB」を 指定しなくてもよいものなのでしょうか。 環境 MySql 4.0.24

    • ベストアンサー
    • MySQL
  • C# トランザクション処理

    DataSetのTableAdapterでSQL Serverへのデータ挿入、更新、削除を行います。 try { ta.UpdataQuery(.....); } catche { Exception; } といった処理をしますが、トランザクション処理をする場合、 try { // トランザクション開始 ta.UpdataQuery(.....); // コミット } catche { // ロールバック Exception; } といった感じになるかと思いますが、どのようにコードを書けばよいのでしょうか?手元にコードがありませんので詳細が書けませんが、よろしくお願いします。

  • オフライン中のトランザクションについて

    表領域をオフラインにした場合、オフライン前に開始されたトランザクションは有効ですが、オフラインのまま、コミット、または、ロールバックして、表領域をオンラインにしても、整合がとれるのはなぜなのでしょうか。 コミットするか、ロールバックするかの情報はどこに保持してるのか疑問です。 (オフラインにしてから、ファイルをリネームし、 トランザクションをロールバックして、 ログをアーカイブし、DB再起動後に、ファイル名を戻して、 オンラインにすると、ちゃんとロールバックされています。 同じ操作で、コミットするとちゃんとコミットされています。 知っている方には当然なのでしょうが、私にとっては、不思議です) 詳しい方がみえましたらご教授お願いいたします。

  • VBS ADO接続について

    VBSCRIPTを使用するのが始めてでなかなかうまくいきません アドバイス頂けますでしょうか。 環境 Windows2000Server 下記のようにしてみたのですが、エラーメッセージとしては 「オブジェクト名'test2'は無効です。」と出てしまいます。 このテーブル'test2'はクエリアナライザでSQLを使って 作成しました。 色々調べてはいますが、できましたらアドバイスの方お願いできますでしょうか。 Private Function DbDataUpdate(id2) Dim sql Dim conObj_ 'DBオブジェクトの生成 Set conObj_ = WScript.CreateObject("ADODB.Connection") conObj_.open "DSN=×××;UID=×××;PWD=×××;" conObj_.BeginTrans sql = "INSERT INTO test (id1, id2) " & _ "SELECT id1, id2 FROM test2 " & _ "WHERE " & _ "del = 0 AND " & _ "id2 = '" & id2 & "'" conObj_.execute(sql) sql = "UPDATE test2 " & _ "SET del = 1," &_ "WHERE " & _ "del = 0 AND " & _ "id2 = '" & id2 & "'" conObj_.execute(sql) conObj_.CommitTrans conObj_.close End Function

  • access adoのトランザクション

    access2003でSQLServer2008へのリンクテーブルを作成し、 vbaでadoを使ってデータ更新処理をしようとしています。 以下のように記述していますが、 実行後、BやCのテーブルが開かなくなります。 (正確にはインサートしたデータが表示されるであろうページがロックされているような動きです。) また、その状態からAccessを一旦終了し、再度起動すると、データがインサートされていない状態です。 コミットが効いてないように感じます。 こちら原因としてどんなことが考えられるでしょうか? ちなみにDAOで動かしても同様でした。 宜しくお願い致します。 以下 コード============================ Set cn = CurrentProject.Connection Set rst = New ADODB.Recordset cn.BeginTrans rst.Open "select key from A", cn, adOpenForwardOnly, adLockReadOnly Do Until rst.EOF cne.Execute "insert into B ( aa, bb) select aa, bb from A where key = " & rst!key & " " cne.Execute "insert into C ( aa, bb) select aa, bb from A where key = " & rst!key & " " rst.MoveNext Loop rst.Close cn.CommitTrans cn.Close set rst = Nothing set cn = Nothing