AccessVBAのトランザクション処理でデータ喪失予防は可能か?

このQ&Aのポイント
  • AccessVBAにおいて、トランザクション処理を使用することでデータ喪失予防が可能です。
  • トランザクション処理を使用すると、エラーが発生した場合に処理前の状態に戻ることができます。
  • この処理は、deleteやinsertといったデータの変更操作に限らず、どのような処理にも有効です。
回答を見る
  • ベストアンサー

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

AccessVBAにてコードを作成する際に、 下記トランザクション処理のコードを書くとデータ喪失予防になると 聞きました。(エラーが起きたときには、処理前に戻ると。) この処理は、delete~insertのような処理でないと有効にならないのでしょうか?どんな処理でも有効ですか? Dim Wrk As workspace Dim blnFlag As Boolean Set Wrk = DBEngine.Workspaces(0) Wrk.BeginTrans blnFlag = True ***************************** delete ~insert (update) ***************************** Wrk.CommitTrans blnFlag = False Set Wrk = Nothing Err: If blnFlag = True Then Wrk.Rollback End If

質問者が選んだベストアンサー

  • ベストアンサー
  • k_sidina
  • ベストアンサー率52% (9/17)
回答No.2

トランザクションはデータ喪失防止のためにあるわけではありません。 データの一貫性の保持等のためにあるのです。 (アクセスの場合、処理を軽くするために使ったりもしますけどね) > どんな処理でも有効ですか? ここでいう「どんな処理」とはどういった処理を想定していらっしゃいますか?

その他の回答 (1)

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

先ず、トランザクション管理の意味を勉強した方が良いでしょう。 つい、先日もこのような質問に答えたばかりです。

関連するQ&A

  • レコード単位にトランザクションかけられる?

    Access2003 Win-XP です。 下記コーディングで現象は・・・ ・2つのPCで同じレコードを編集すると、あとから編集する人は待機中になる。 ・しかしながら、同じテーブルで最初にレコード編集中の人がいたとき、別PCの人が別レコードを編集することは可能で待機することはない(これは正常)。そして正常に更新されたかのように終了する。しかしながら、更新はされていない。   (更新されないのにエラーハンドリングできない) これはいったいどういうことでしょうか? 何か対策はないでしょうか? Dim ret_value As Variant Dim wsp As Workspace Dim dbs As Database Dim rsA Set wsp = DBEngine.Workspaces(0) Set dbs = CurrentDb wsp.BeginTrans Set rsA = dbs.OpenRecordset("在籍表", dbOpenDynaset, dbSeeChanges, dbPessimistic) Do Until rsA.EOF If rsA.[出席番号] = Me.[出席番号] Then rsA.Edit rsA.[氏名] = Me.[氏名] rsA.Update rsA.MoveLast End If rsA.MoveNext Loop rsA.Close ret_value = MsgBox("Commit ?", vbYesNo) If ret_value = vbYes Then wsp.CommitTrans Me.Requery Else wsp.Rollback End If Exit_コマンド34_Click: Set wsp = Nothing Exit Sub Err_コマンド34_Click: MsgBox Err.Description Resume Exit_コマンド34_Click  

  • 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直前で処理を止められるようにしました。

  • [性能改善]AccessのDBに大量のデータをUpdateする場合の性能対策について

    初めまして。 早速質問なのですが、VB(6.0)でmdb(Access2000)のDBを更新する処理を作りました。 DAOを用いて(初めて使います)以下のような構文を作ったのですが、 性能がぱっとしません。 何か下記のソースをいじることで性能が改善するような手立てはありませんでしょうか? ---------------------------------------------------------------------- Sub Main()      Dim cDaoDB    As DAO.Database      Dim cDaoWS    As Workspace      Dim cColUpdate  As Collection      Dim varColItem  As Variant      Dim lngCnt    As Long      Set cDaoWS = DBEngine.Workspaces(0)      Set cDaoDB = mDaoWS.OpenDatabase("C:\TEST.mdb")      'コレクションにデータをaddする処理は省略しています      cColUpdate.add            With cDaoDB           cDaoWS.BeginTrans           'cColUpdateコレクションには10万件ほどのSQL構文(Update構文)が格納されています           '10万回ほど繰り返し処理します           For Each varColItem In cColUpdate                lngCnt = lngCnt + 1                If lngCnt > 1000 Then                     'データ量が多いため1000件ごとにコミットしています                     cDaoWS.CommitTrans                     cDaoWS.BeginTrans                     lngCnt = 0                End If                strErrSQL = varColItem                'Update処理が繰り返し流れます。                .Execute varColItem           Next           .Close           cDaoWS.Close      End With      Set cDaoDB = Nothing      Set cDaoWS = Nothing End Sub ---------------------------------------------------------------------- よろしくお願いします。

  • Accessdでの「トランザクションが多すぎる」エラーとは何?

    Access98のVBAでプログラムを組み、RecordsetをUpdateしたり、Deleteしたりしていると、『実行時エラー'3003':ネストしているトランザクションが多すぎるため、トランザクションを開始できませんでした』とエラーが発生します。 「トランザクション」の意味が分かりませんが、プログラムの中では、「トランザクション」なるモノを定義や設定したりしておりません。 ヘルプを閲覧すると「BeginTrans」「CommitTrans」「Rollback」と云う難しそうな言葉が出てきました。 エラーが発生しないようにするためには、プログラムの中にどの様なエラー回避の語を書き込んで置けば良いのでしょうか?

  • AccessVBAコミットとロールバックの位置

    いつもお世話になっております。 BeginTrans、CommitTrans、RollbackTransの記述位置について お聞きしたい事があります。 合計で2のテーブルにインサート処理を行います。 Private Sub cmd_Click() Dim strSQL AS String '(1)adoコネクション生成 Set dbCon = Application.CurrentProject.Connection strSQL = "テーブルAに挿入するInsert文" '(2)テーブルaにデータ挿入 dbCon.Execute (strSQL) '(3)テーブルaのデータをレコードセットへ strSQL = "SELECT * FROM テーブルA" Set dbRes = dbCon.Execute(strSQL) Do Until dbRes.EOF ==================================================== ここでdbResの値を使用してテーブルbへ挿入するSQL文を作成 ==================================================== Loop '(4)テーブルbにデータ挿入 dbCon.Execute (strSQL) 以上の場合、テーブルaへのInsert文をCommitTransしなければ テーブルbで使用するためデータを作成できません。 (4)でエラーが発生するとテーブルaは更新確定されているので戻り事ができないのですが どのようにCommitTransを使用すればよろしいでしょうか?? テーブルaの挿入が失敗した場合は処理を抜けて テーブルbの挿入が失敗した場合はテーブルaを元の状態(RollbackTrans)したいです。 ご教授お願い致しますm( _ _)m

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

    VB2005、SQLServer2005環境です。 VB.Netのトランザクション処理でエラーが発生します。 エラー内容の意味すらわかりません。 どなたかご教授お願いします。 *エラー内容 "System.InvalidOperationException: ExecuteReader は、コマンドに割り当てられた接続が保留状態である ローカルのトランザクションにあるとき、トランザクション オブジェクトを持つコマンドが必要です。 コマンドの Transaction プロパティがまだ初期化されていません。 Private Sub BTN_更新_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTN_更新.Click Dim strsql As String Dim Tran As SqlClient.SqlTransaction = Nothing '---DB接続 Call DBConnect() Try '---SQL文作成 strsql = "SELECT * FROM Aテーブル" '---SQL文を作成して実行する Dim comm As SqlCommand = New SqlCommand(strsql, Con) '---データアダプタの作成 Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm) '---データセットへの読み込み Dim ds As DataSet = New DataSet() dataadapter.Fill(ds, "Aテーブル") Dim dt As New DataTable dt = ds.Tables("Aテーブル") '---主キーの設定 dt.PrimaryKey = New DataColumn() {dt.Columns("Aテーブル")} '---データの更新 Dim targetRow As DataRow targetRow = dt.NewRow() targetRow = dt.Rows.Find(TXT_コード.Text) targetRow("コード") = TXT_コード.Text targetRow("氏名") = TXT_氏名.Text '---コマンド自動作成 Dim cb As SqlCommandBuilder = New SqlCommandBuilder(dataadapter) '---トランザクション開始 Tran = Con.BeginTransaction() '---データベースの更新 dataadapter.Update(ds, "社員テーブル")     <<<エラーになります。 '---トランザクション完了 Tran.Commit() Catch oExcept As Exception '---ロールバック Tran.Rollback() '例外が発生した時の処理 MessageBox.Show(oExcept.ToString, "例外発生") Finally '---DB切断 Call Disconnect() End Try

  • VBAでoo4oを使用してINSERTする際にエラーが発生

    Excelのマクロでoo4oを使用してINSERTをしようとしています。 Dim OraSession As OraSession Dim OraDatabase As OraDatabase Set OraSession = CreateObject("OracleInProcServer.XOraSession") Set OraDatabase = OraSession.OpenDatabase(TNS, USER/PASS, 0&) OraSession.BeginTrans OraDatabase.ExecuteSQL("Insert Into tablename ( colum1, colum2) VALUES( '12345', '1234');") OraSession.BeginTrans OraDatabase.ExecuteSQLでINSERTしようとした場合に、「ORA-00911: 文字が無効です。」とエラーになってしまいます。 同じSQL文をSQL PLUS+で実行させた場合、正常にINSERTができます。 何か特別な処理をしないといけないのでしょうか。 よろしくお願いします。

  • insert1つの処理でもトランザクションは必要?

    お世話になります。 現在、MYSQLデータベースを使用したプログラムを書いており、 そこでトランザクションについて質問があります。 トランザクションとは、複数の処理がすべて成功した場合に正式な処理を実行(commit)、1つでも失敗した場合は元に戻す(rollback)というようなことかと思うのですが、 では、1つの処理のみの場合は、トランザクションを使用する必要はないのでしょうか? 例えば、 ・あるテーブルにデータをinsertしたい。 このような単一の処理を書く場合でも、 以下のようにトランザクションを使うべきでしょうか? $dsn = 'mysql:dbname=〇〇〇;host=〇〇〇;charset=utf8'; $user = 'user'; $pwd = 'pwd'; //DB接続 try { $pdo = new PDO($dsn, $user, $pwd); } catch (PDOException $e) { die('DB接続失敗'); } //トランザクション開始 $pdo->beginTransaction(); //INSERT try { $sql = 'INSERT into table (test1, test2, test3) VALUES (:a, :b, :c)'; $st= $pdo->prepare($sql); $ret = $st->execute(array( ':a' => $a, ':b' => $b, ':c' => $c, )); if (!$ret) { throw new Exception('INSERT 失敗'); } //commit $pdo->commit(); } catch (PDOException $e) { //rollback $pdo->rollBack(); } $pdo = null; ※前提として、テーブルを使用するユーザーは多数います。 ご存知の方、ご回答いただけるれば幸いです。 よろしくお願い致します。

    • ベストアンサー
    • PHP
  • 初歩的なSQLですが・・・

    私の環境はOS:Xp      ACCESS2000です。 宜しくお願いします 今AccessVBAで作業をしているのですが、 Dim ws As DAO.Workspace Dim DB As DAO.Database Dim rs As DAO.Recordset Dim sql As String Set ws = DBEngine.Workspaces(0) Set DB = ws.Databases(0) sql = "select MAX(銀行コード) from 銀行テーブル ;" Set rs = DB.OpenRecordset(sql) Me.合計 = rs このSQL文で銀行テーブルに入っている銀行コードの最大値を取得したいのですが、取得した後どのように記述したら「rs」から値を引っ張り出せるのでしょうか? 宜しくお願いします。

  • 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