views:

3938

answers:

3

Hi,

I develop one application using VB.net (200%) that connects to MS-Access Database, I use TableAdapter and Dataset for connection to the Access DB file.

I need to implement a simple transaction method (commit, rollback) in saving to the DB?

Is there a way to do that without the need to use inline SQL statement?

Thanks,

A: 

You can find a bunch of data access tutorials at http://www.asp.net/learn/data-access/

+3  A: 

As I read Microsoft Jet (Access DB Engine) supports transactions. So you can create a transaction like this (example from CodeProject):

      SqlConnection db = new SqlConnection("connstringhere");
      SqlTransaction transaction;

      db.Open();
      transaction = db.BeginTransaction();
      try 
      {
         new SqlCommand("INSERT INTO TransactionDemo " +
            "(Text) VALUES ('Row1');", db, transaction)
            .ExecuteNonQuery();
         new SqlCommand("INSERT INTO TransactionDemo " +
            "(Text) VALUES ('Row2');", db, transaction)
            .ExecuteNonQuery();
         new SqlCommand("INSERT INTO CrashMeNow VALUES " +
            "('Die', 'Die', 'Die');", db, transaction)
            .ExecuteNonQuery();
         transaction.Commit();
      } 
      catch (SqlException sqlError) 
      {
         transaction.Rollback();
      }
      db.Close();

An easier way is (example from 15 Seconds):

bool IsConsistent = false;

using (System.Transactions.TransactionScope ts = new System.Transactions.TransactionScope())

{

      SqlConnection cn = newSqlConnection(CONNECTION_STRING );

      string sql = "DELETE Categories";

      SqlCommand cmd = newSqlCommand(sql, cn);

      cn.Open();

      cmd.ExecuteNonQuery();

      cn.Close();

      //Based on this property the transaction will commit if

      //successful.  If it fails however, this property will

      //not be set and the transaction will not commit.

      ts.Consistent = IsConsistent;

}

You will need MSDTC running on your machine if you are using TransactionScope.

Unfortunately TableAdapter does not expose a connection property, so you need a workaround. So you need some workaround:

1) Reflection (example form CodeProject)

conn = new SqlConnection(Properties.Settings.Default.NorthwindConnectionString);
conn.Open();
trans = conn.BeginTransaction();
1. 
public SqlDataAdapter GetAdapter(object tableAdapter)
{
    Type tableAdapterType = tableAdapter.GetType();
    SqlDataAdapter adapter = (SqlDataAdapter)tableAdapterType.GetProperty("Adapter", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tableAdapter, null);
        return adapter;
}
2.
adapter.InsertCommand.Connection = trans.Connection;
adapter.UpdateCommand.Connection = trans.Connection;
adapter.DeleteCommand.Connection = trans.Connection;

3.
adapter.InsertCommand.Transaction = trans;
adapter.UpdateCommand.Transaction = trans;
adapter.DeleteCommand.Transaction = trans;

4. 
-

5. 
trans.commit();

Reflection can be very slow!

2) TransactionScope (example form DevX.com)

    CustomersDataSet.CustomersDataTable customers = new CustomersDataSet.CustomersDataTable();
   CustomersDataSetTableAdapters.CustomersTableAdapter tblAdap = new 
      CustomersDataSetTableAdapters.CustomersTableAdapter();
   using (TransactionScope txScope = new TransactionScope())
   {
       tblAdap.Fill(customers);
       customers.Rows[0]["ContactName"] = "Maria Velasquez";
       tblAdap.Update(customers);
       txScope.Complete();
   }

You will need MSDTC!

artur02
TableAdapters CAN expose a connection property, if you right click on the adapter in the designer, go to Properties, and then change the ConnectionModifier property to Public. I use this to allow me to share a single connection for multiple table adapters and therefore prevent promotion to DTC when using TransactionScope.
patmortech
Wow, thats an awful lot of good work for someone who never came back.
RBarryYoung
A: 

Maybe a lot for someone who never came back, but I know I sure found it useful.

mwilken