none
請問 OleDbDataAdapter 的批次處理可以支援交易嗎? RRS feed

  • 問題

  • 各位好:

          請問 我可以用 OleDbDataAdapter 配合 OleDbTransation 達到交易的功能嗎?

     

    2008年5月7日 上午 12:06

解答

  •  

    抱歉, 沒看清楚你的問題, 不過還是可以的

     

                OleDbConnection conn = new OleDbConnection("connectionString...");
                OleDbDataAdapter adapter = new OleDbDataAdapter("SQL語法", conn);
                OleDbCommandBuilder commandBuilder = new OleDbCommandBuilder(da);
                adapter.UpdateCommand = commandBuilder.GetUpdateCommand();
                conn.Open();
                OleDbTransaction transaction = conn.BeginTransaction();
                adapter.UpdateCommand.Transaction = transaction;

                try
                {
                    adapter.Update(dataTable);
                    transaction.Commit();
                }
                catch (Exception e)
                {
                    transaction.Rollback();
                }
                finally
                {
                    conn.Close();
                }

     

    手邊沒有環境測試, 所以如果有錯的請見諒 Smile

    2008年5月7日 上午 01:08

所有回覆

  •  

    可以. 請參考程式碼

    OleDbConnection conn = new OleDbConnection("connection String...");
    conn.Open();
    OleDbTransaction transaction = conn.BeginTransaction();
    OleDbCommand cmd = new OleDbCommand("SQL語法1", conn, transaction);
    cmd.ExecuteNonQuery();
    OleDbCommand selectCmd = new OleDbCommand("SQL語法2", conn, transaction);
    OleDbDataAdapter da = new OleDbDataAdapter(selectCmd);
    DataSet ds = new DataSet();
    da.Fill(ds, "資料表");
    transaction.Commit();
    conn.Close();

    2008年5月7日 上午 12:40
  •  

    您好:

          因為 OleDbAdapter.UpDate 結束後不是會將 Connection 關閉,它這樣可以使用 Transaction 嗎?

    2008年5月7日 上午 12:45
  •  

    抱歉, 沒看清楚你的問題, 不過還是可以的

     

                OleDbConnection conn = new OleDbConnection("connectionString...");
                OleDbDataAdapter adapter = new OleDbDataAdapter("SQL語法", conn);
                OleDbCommandBuilder commandBuilder = new OleDbCommandBuilder(da);
                adapter.UpdateCommand = commandBuilder.GetUpdateCommand();
                conn.Open();
                OleDbTransaction transaction = conn.BeginTransaction();
                adapter.UpdateCommand.Transaction = transaction;

                try
                {
                    adapter.Update(dataTable);
                    transaction.Commit();
                }
                catch (Exception e)
                {
                    transaction.Rollback();
                }
                finally
                {
                    conn.Close();
                }

     

    手邊沒有環境測試, 所以如果有錯的請見諒 Smile

    2008年5月7日 上午 01:08
  • dear 楊毛:

         請問一下您 OleDbCommandBuilder commandBuilder = new OleDbCommandBuilder(da);

    中的 da 是指上面的 adapter嗎?

     

    以下是我的程式碼

    using (OleDbConnection conn = new OleDbConnection(DbConnectionString))
    {             
            OleDbCommand cmd = new OleDbCommand(sqlquery, conn);
            OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
            OleDbCommandBuilder cmdb = new OleDbCommandBuilder(adapter);

            conn.Open();

            OleDbTransaction transaction = conn.BeginTransaction();
            adapter.UpdateCommand = cmdb.GetUpdateCommand();

             try
              {
                    cmdb.GetUpdateCommand().Transaction = transaction;
                        
                    affRow = adapter.Update(dt);
                    transaction.Rollback();
              }
              catch (DBConcurrencyException e2)      //無影響筆數
              {
                    affRow = 0;
              }
              catch (OleDbException e3)
              {
                    affRow = e3.ErrorCode;
              }
    }

     

     

     

    在做

    adapter.UpdateCommand = CommandBuilder.GetUpdateCommand();

    會有下列的錯誤訊息

    當指定給命令的連接為擱置的本機交易時,ExecuteReader 需要連接以交易。命令的 Transaction 屬性尚未初始化。

    2008年5月7日 上午 03:04
  • Code Snippet

    using (OleDbConnection conn = new OleDbConnection(DbConnectionString))
    {             
            OleDbCommand cmd = new OleDbCommand(sqlquery, conn);
            OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
            OleDbCommandBuilder cmdb = new OleDbCommandBuilder(adapter);

            conn.Open();

            OleDbTransaction transaction = conn.BeginTransaction();
            adapter.UpdateCommand = cmdb.GetUpdateCommand();

             try
              {
                   cmdb.GetUpdateCommand().Transaction = transaction; // 不能這樣
                   cmdb.UpdateCommand.Transaction = transaction; // 這樣才對。

        
                    affRow = adapter.Update(dt);
                    transaction.Rollback(); // 你這樣會讓成功的變更被撤回 ...

                    transaction.Commit(); // 這樣才對
              }
              catch (DBConcurrencyException e2)      //無影響筆數
              {
                    affRow = 0;

                    transaction.Rollback(); // 錯誤撤回的程式應放在 catch 內。
              }
              catch (OleDbException e3)
              {
                    affRow = e3.ErrorCode;

                    transaction.Rollback();
              }
    }

     

     

    另外,BeginTransaction 到 Commit 的時間要愈短愈好,以免資源被鎖定太久造成死結或 Timeout。

    2008年5月7日 上午 03:23
    版主
  •  

    找到問題了,原來

    adapter.UpdateCommand = cmdb.GetUpdateCommand();

    要在 OleDbTransaction transaction = conn.BeginTransaction(); 

     

    之前

     

    謝謝兩位的解答


                       

     

     

     


     

    2008年5月7日 上午 03:23