• 締切済み

VB5+SQL2000での ** TRANSACTIONについて(ADO)

環境:VB5(SP3)+SQL2000(SP1) VBで、BEGIN TRANSACTIONを定義し、その後更新用DBを更新する前に、ストアドプロシージャを利用せずDBを検索した場合、問題無く更新用DBへの更新に対して(ROLLBACK/COMMIT) TRANSACTION が効くのですが、ストアドプロシージャで検索した場合、(ROLLBACK) TRANSACTION が効きません。 分かりづらいですがサンプルを記します。 Function Test() Dim MyRs As New ADODB.Recordset Dim MyRs2 As New ADODB.Recordset : MyDB.Execute "BEGIN TRANSACTION TEST999",,adCmdText+adExecuteNoRecords : '(A)不具合未発生パターン 'レコードセットを開く 'このように、レコードセットを作成した場合問題なし。 MyRs.Open "SELECT * FROM TESTDB..テスト",MyDB,adOpenStatic '(B)不具合発生パターン 'ただし、上のSELECT文をストアドプロシージャで開いた場合、ROLLBACKが効かない 'レコードセットを開く(正常に(ROLLBACK)TRANSACTIONが動作せず、UpDate時にCommitしている) 'MyRs.Open "TESTDB..TEST001",MyDB,adOpenStatic : MyRs2.Open "SELECT * FROM TESTDB..更新テスト",MyDB,adOpenKeyset,adLockPessimistic If Err <> 0 Then 'Error処理 End If If MyRs2.EOF Then MyRs2.AddNew MyRs2![FLD1] = MyRs2![FLD1A] Else MyRs2![FLD1] = "TEST" End If MyRs2.UpDate 'ここは正常終了。(Err = 0) 'テスト用にエラー設定 Err = 1 if Err <> 0 then '(B)不具合発生パターンの場合、ROLLBACK をしても、DBに登録されてしまう。 MyDB.Execute "ROLLBACK TRANSACTION TEST999",,adCmdText+adExecuteNoRecords Exit Function End If MyRs.Close MyRs2.Close SmileDB.Execute "COMMIT TRANSACTION TEST999",,adCmdText+adExecuteNoRecords End Function

みんなの回答

  • mann555
  • ベストアンサー率46% (29/62)
回答No.1

確か「.Execute」でSQL発行した場合、発行した時点でcommitされ Rollbackできなかったような… 下の方法ではどうですか? Mydb.BeginTrans    ・ Mydb.Update Mydb.CommitTrans    ・    ・    ・ Mydb.RollbackTrans

関連するQ&A

  • Transactionで待機状態になりません

    Access2003 Win-XPです。 ネットワーク上にmdbを置いて、複数ユーザーで共用して使用していますが、マルチユーザー環境での制御が出来ません。 具体的には、ある人(Aさん)がBeginTransからCommitする間に別の人(Bさん)が同じデータを更新しようとしてBeginTransをスルーしてしまいます。 待機状態になりません。 (いわゆるLockの概念とは違うのでしょうか?) 確かに、Bさんの更新はテーブルへ反映されることはないのですが、何もなかったようにスルーして処理が進んでしまいます。 エラーにもならないのでハンドリングしようがないです。 これでは、Bさんはあたかも自分の更新が成功したかのように錯覚をしてしまいます。 分厚い壁にぶち当たり、何をどうしたらよいのかまったくわかりません。 どなたかご教授ください。 具体的なコーディングは下記です。 Dim ret_value As Variant Dim wsp As Workspace Dim dbs As Database Set wsp = DBEngine.Workspaces(0) Set dbs = CurrentDb wsp.BeginTrans  dbs.Execute "update [tm_memory_card] set [機種] = '" & Me.[機    種] & "'" dbs.Close ret_value = MsgBox("Commit ?", vbYesNo) If ret_value = vbYes Then wsp.CommitTrans Me.Requery Else wsp.Rollback End If テストしやすいように、Commit直前で処理を止められるようにしました。

  • DAOでテーブルの内容を検索したいのですが…

    DAOでテーブルの内容を検索したいのですが… アクセス初心者です。 フォームで取得した値をテーブルで検索して命令するために,次のようなことをしてみましたが,FindFirstのところでエラーがでます。 どうしたらよいのかご指導ください。 コマンドボタンのイベントプロシージャで Private Sub テストテーブル作成_Click() Dim gakki As Integer Dim test As Integer Me.学期 = gakki Me.テスト = test Call testテーブル作成 End Sub として,標準モジュールに Sub testテーブル作成() Dim myDB As DAO.Database Dim myRS As DAO.Recordset Set myDB = CurrentDb Set myRS = myDB.OpenRecordset("T_生徒テスト") myRS.FindFirst "学期ID=" & "" & "gakki" & "" & "AND テストID =" & "" & "test" & "" If myRS.NoMatch = False Then DoCmd.OpenQuery "Q_TSテストA" DoCmd.OpenForm "F_テスト" DoCmd.Close Else DoCmd.OpenQuery "Q_TSテスト" DoCmd.OpenQuery "Q_テスト" DoCmd.Close DoCmd.OpenForm "F_テスト" End If myRS.Close: Set myRS = Nothing myDB.Close: Set myDB = Nothing End Sub としました。よろしくお願いします。

  • VB.Net TableAdapterで登録してい

    お世話になります。 VB.Net 駆け出しの者です TableAdapter に登録してあるストアドプロシジャーをよく実行しますが、 Dim Ret Integer Ret = Me.問題のTableAdapter.問題の関数(引数) こんな感じで実行しますが、実行後の戻り値は1か0の 反映した件数?!が帰ってきると思われるのですが、ストアド内のReTurn で返している値を取得するにはどうしたらよいのでしょうか? 例えば、ストアドプロシジャーの最後の部分で、下記のようにオートナンバーのキーを取得したい場合、ReturnValue の値を取得したいことってあると思うのですが、こういう場合、TableAdapter.関数の記述でReturnValue の値を取得するためにはどのような記述をすればいいのでしょうか? 何卒よろしくお願いいたします。 SET @Ret = @@IDENTITY COMMIT TRANSACTION RETURN @Ret END TRY BEGIN CATCH ROLLBACK TRANSACTION RETURN 0 END CATCH

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

    トランザクションについての質問なのですが、下にある1のSQLを実行すると 'a'だけ登録されるのは、分かるのですが、 2のSQLを実行すると、'c'と'd'の両方が登録されてしまいます。 私的には、両方登録されないのかなぁと思っていたのですが・・・ COMMITが来た時点で、START TRANSACTIONの開始位置は、 あまり関係ないということなのでしょうか? よろしくお願いします。 1. START TRANSACTION; insert into test values('a'); START TRANSACTION; insert into mtuser values('b'); ROLLBACK; COMMIT; 2. START TRANSACTION; insert into test values('c'); START TRANSACTION; insert into mtuser values('d'); COMMIT; ROLLBACK; 環境:Mysql4.1.19

    • ベストアンサー
    • MySQL
  • VB.NETでADOでOracleのストアドを起動

    いつも楽しく勉強させていただいております。 環境はWindows Server 2008R2 DataCenter、データベースはOracle10G、開発ツールはVB.NET2015です。 このたびWindows Server 2003のVB6.0から上記の環境に乗せ換えているところです(Oracleのバージョンは変わりなし)。 最初にVB6.0からVB.NETへの変換はかけましたが、 なるべくVBのソースは変更しないという制約があります(テストのし直しが膨大になるので)。 VBとOracleはADOを使って接続しています。 ADOを使ってテーブルの読み書きはできるのですが、ストアドプロシージャの起動がうまくいきません。 具体的には入力パラメータはストアドに渡って処理も動くのですが、出力パラメータが返ってきません。 ストアドが正しく動くことはObjectBrowserで確認済みです。 下記のソースはVB6.0で動いていたものですが、VB.NET2015では二つの出力パラメータの値がNothingとなります。 (本来ならステータスとメッセージが返ります)。 VB.NET2015でADOでストアドを使うことは無理なのでしょうか。 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim Cnn As New ADODB.Connection Dim cmd As New ADODB.Command Dim Prm As New ADODB.Parameter Dim strMsg As String On Error GoTo Err_cmdExec_Click With Cnn .Provider = "MSDASQL" .ConnectionString = "DSN=DB1;" & "UID=abc;" & "PWD=efg" .Open() End With 'ストアドプロシージャ呼び出し設定&呼び出し With cmd .CommandTimeout = 0 'タイムアウト設定を無制限に .ActiveConnection = Cnn 'サーバー接続設定 .CommandText = "CHECK_PROC" 'ストアド名セット .CommandType = ADODB.CommandTypeEnum.adCmdStoredProc 'ストアドなのでadCmdStoredProc Prm = .CreateParameter("p_yyyymm", ADODB.DataTypeEnum.adChar, ADODB.ParameterDirectionEnum.adParamInput, 6, "201601") cmd.Parameters.Append(Prm) Prm = .CreateParameter("p_sts", ADODB.DataTypeEnum.adChar, ADODB.ParameterDirectionEnum.adParamOutput, 1) cmd.Parameters.Append(Prm) Prm = .CreateParameter("p_msg", ADODB.DataTypeEnum.adVarChar, ADODB.ParameterDirectionEnum.adParamOutput, 512) cmd.Parameters.Append(Prm) '実行 .Execute() '戻り値の判断&表示用メッセージ生成 If .Parameters.Item("p_sts").Value = "0" Then strMsg = "正常終了しました" Else strMsg = "異常終了しました" & vbCrLf & "ErrMsg=" & .Parameters.Item("p_msg").Value End If End With Exit_cmdExec_Click: '接続解除 Cnn.Close() 'Set Cnn = Nothing 'メッセージ表示 MsgBox(strMsg) Exit Sub Err_cmdExec_Click: 'ストアド以外の場所でのエラーなので、VBのErrの情報セット strMsg = "異常終了しました" & vbCrLf & "ErrNO=" & Err.Number & " ErrMsg=" & Err.Description Resume Exit_cmdExec_Click End Sub

  • postgresqlのトランザクションについて

    開発環境(centOS、apatch、php、postgresql) postgrsqlで「current transaction is aborted, commands ignored until end of transaction block」 のエラーが出てしまいました。 ・複数テーブルに対してinsertを行っています。 ・複数tableのinsert中のどこかでエラーになった場合、全tableをrollbackしたいです。 ・複数テーブルのうち、ひとつのtableでは5回insertを行っています。   for文でまわしているのですが、ここで2回目のinsertの時に   上記のエラーになってしまいます。 で、トランザクション(begin、rollback、commit)を全てはずしたところ、全てのtableで正常にinsertできました。 上記のエラーを調べてみても rollbackしていない・・・みたいなことしか調べられませんでした。 エラーにはなっていないのでrollbackはしないし、ここでcommitしてしまうと、次のinsertなどでエラーになった時、rollbackできなくなってしまうし。。。 上記のエラーをなくすために どのような対策をすればいいのかアドバイスをお願いいたします!

  • 下記質問Vol.3です

    If intSr = 1 Then intRes = MsgBox("追加してもO.K.ですか?", vbYesNo + vbQuestion) If intRes = vbYes Then With cmd .ActiveConnection = cn .CommandType = adCmdText .CommandText = strSQL .Execute End With Call 状態変化(2) End If Else intRes2 = MsgBox("更新しても良いですか?", vbYesNo + vbQuestion) If intRes2 = vbYes Then With cmd .ActiveConnection = cn .CommandType = adCmdText .CommandText = strSQL2 .Execute End With Call 状態変化(2) End If End If End Sub よろしくお願いします。 関連URL:http://www.okweb.ne.jp/kotaeru.php3?q=160999 http://www.okweb.ne.jp/kotaeru.php3?q=161003

  • データをロック中にエラーチェックを行うべきか?

    PHP5.2.4、MySQLバージョン4.1.16を使用しています。 次のように、データをロックする前にエラーチェックを行い、 エラーじゃなかったら更新処理を行うという書き方なのですが、 これだとエラーチェックとSTART TRANSACTION;(ロック開始)の 間で$pointが10以上になるか心配なのですが、そのようなことは ありえるのでしょうか? 心配するぐらいならSTART TRANSACTION;してから エラーチェックを書けばいいのでしょうが、 それだとROLLBACKの処理も絡んできそうで厄介なので できればこのように書きたいのですが・・・ ※ $pointとはそのユーザが所有しているデータの一部です(つまり任意のタイミングで書き換えが可能) if ($point >= 10)//←ここでチェックを行い、エラーなら抜ける {  error('pointが10以上です');  exit(); } ↑ // この間で$pointが10以上になる可能性が心配 ↓ START TRANSACTION;//←ロック開始 //ここに更新処理 COMMIT;

    • ベストアンサー
    • PHP
  • Excelを更新するADOの書き方を教えて下さい。

      .Provider = "MSDASQL"   cnn.ConnectionString = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" & _               "DBQ=" & xlFileName & ";" & _               "ReadOnly=False;"   If isHeader Then     .Properties("Extended Properties") = "Excel 12.0;HDR=YES;IMEX=1"   Else     .Properties("Extended Properties") = "Excel 12.0;HDR=NO;IMEX=1"   End If   .Open   .Execute strSQL という書き方では、動作します。また、"Microsoft.ACE.OLEDB.12.0;"バージョンでも   cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strDB & ";"   With cnn      .Errors.Clear      .BeginTrans      .Execute strSQL      .CommitTrans   End With という書き方で、Access の mdb は更新できます。エクセルのシートを Recordset としてオープンすれば、下記の接続設定でも読むことは出来ます。非同期を指定すれば、エラーは回避できますがシートは更新されていません。当方、VBAを書くのは1996年以来。なんとか、この問題を解決して一区切りを付けたいと思っています。宜しく、ご協力の程お願いしておきます。 Public Function SQLExecute(ByVal strSQL As String, _               Optional xlFileName As String = "", _               Optional isHeader As Boolean = True) As Boolean On Error GoTo Err_SQLExecute   Dim isOK As Boolean   Dim DataValue   Dim cnn As ADODB.Connection     isOK = True   Set cnn = New ADODB.Connection   '   ' ThisWorkbook.FullName の指定   '   If Not Len(xlFileName) Then      xlFileName = ThisWorkbook.FullName   End If   '   ' 接続設定   '   With cnn     .Provider = "Microsoft.ACE.OLEDB.12.0;"     If isHeader Then       .Properties("Extended Properties") = "Excel 12.0;HDR=YES;IMEX=1"     Else       .Properties("Extended Properties") = "Excel 12.0;HDR=NO;IMEX=1"     End If     .Open xlFileName     .Errors.Clear     .BeginTrans     .Execute strSQL     .CommitTrans   End With Exit_SQLExecute: On Error Resume Next   cnn.Close   Set cnn = Nothing   SQLExecute = isOK   Exit Function Err_SQLExecute:   isOK = False   If cnn.Errors.Count > 0 Then     ErrMessage cnn.Errors(0), strSQL     cnn.RollbackTrans   Else     MsgBox "プログラムエラーが発生しました。" & _         "システム管理者に報告して下さい。(SQLExecute)", _         vbExclamation, " 関数エラーメッセージ"   End If   Resume Exit_SQLExecute End Function

  • ADO Connection を再利用する方法

    【環境】 OS:Windows Server 2003 DB:SQL Server 2005 言語:VB .NET 2005 現在、Windows2000Server + SQLServer2000 + VB6の環境を 上記の環境に移行しております。 ADO Connectionの再利用で 「手動または分散トランザクションモードのため、新規接続を作成できません」 というエラーが発生します。 いろいろと検索してみたのですが、解決せず、お力をお貸しいただきたいと思って投稿させていただきます。 現在のコードは、 -------------------------------------------- Public adoCn As ADODB.Connection Public adoRs As ADODB.Recordset Public Sub pfAutoClosed()  If fGet印刷ジャーナルファイルRecordset() = True Then    '*********************    'トランザクションの開始    '*********************    adoCn.BeginTrans()    '印刷ジャーナルファイルのロック    sMySQL = "SELECT * FROM 印刷ジャーナルファイル WITH (TABLOCKX)"    adoCn.Execute(sMySQL, , ADODB.CommandTypeEnum.adCmdText)    '職員表マスタのロック    sMySQL = "SELECT * FROM 職員表マスタ WITH (TABLOCKX)"    adoCn.Execute(sMySQL, , ADODB.CommandTypeEnum.adCmdText) <---- ここでエラー発生    adoRs.MoveFirst()    Do Until adoRs.EOF      iKubun = nz(adoRs.Fields("区分").Value)      '*****************      '1.職員表マスタの作成      '*****************      'SQLステートメントを作成      sMySQL = "INSERT INTO 職員表マスタ (~以下省略)"      adoCn.Execute(sMySQL, , ADODB.CommandTypeEnum.adCmdText)      '**************************      '2.更新区分に更新フラグを設定      '**************************      sMySQL = "UPDATE 印刷ジャーナルファイル " & "SET 更新区分 = 1 (~以下省略)"      adoCn.Execute(sMySQL, , ADODB.CommandTypeEnum.adCmdText)      adoRs.MoveNext()    Loop    adoCn.CommitTrans() 'トランザクション処理のコミット    adoRs.Close()    adoRs = Nothing  endif End Sub '***************************************** '印刷ジャーナルファイルのレコードセットを取得 '***************************************** Private Function fGet印刷ジャーナルファイルRecordset() As Boolean   adoRs = New ADODB.Recordset   With adoRs     .let_Source("SELECT * FROM 印刷ジャーナルファイル " & "WHERE 発行区分 = 1 AND 更新区分 = 0")     .let_ActiveConnection(adoCn)     .CursorType = ADODB.CursorTypeEnum.adOpenKeyset     .LockType = ADODB.LockTypeEnum.adLockPessimistic     .Open()   End With   If adoRs.EOF Then     fGet印刷ジャーナルファイルRecordset = False   Else     fGet印刷ジャーナルファイルRecordset = True   End If End Function -------------------------------------------- となっています。 pfAutoClosed関数内で、同じadoCnを使用しての2度目のSELECT文が実行できません。 ADO Connectionの再利用ができないということで、「Close」をしてくださいという記述を参考にもしたのですが、解決しておりません。 トランザクション開始位置も変更してみたのですが、だめでした。 VB->VB.NETへのアップグレードウィザードを使用したのですが、移行以前のVB6のバージョンではエラーなく動作します。 間違っている点をご指南いただければと思います。 よろしくお願いいたします。

専門家に質問してみよう