问题
I have been doing codes that do DELETE, UPDATE, INSERT, SELECT in Databases in school. The problem is that it can do just one query simultaneously. Something like this:
OleDbConnection con = DAL.GetConnection();
con.Open();
if (con.State == ConnectionState.Open) //si la conexion esta abierta...
{
string sql = string.Format(" INSERT INTO lol (...)");
//----->I shortened this above because it's not important <-----
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = sql;
int num = cmd.ExecuteNonQuery();
con.Close();
if (num == 0)
{
Response.Redirect("register.aspx?err=Error");
}
else
{
Session["id"] = MyDB.GetUserId(uname);
Response.Redirect("home.aspx");
}
}
Once my teacher said me that there's something, that works like this: you do all the SQL queries, or no one. I would want to know how to this, it would be really helpful.
Thanks!
回答1:
Your teacher is referring to Transactions. Most relational databases support transactions, including MySQL*. Transactions allow for atomic behavior of multiple CRUD operations. This means that if one operation fails the database will roll back any changes that were made as if none of the operations ever occurred.
Keep in mind that they are running sequentially, not simultaneously. However, since they are atomic it feel feel similar to it running everything in a single operation.
In order to run a transaction using the OleDbConnection class using C# you can create a transaction from your connection object, assuming that it's open. Keep in mind though that unlike with a stored procedure you need to manually commit or rollback the transaction.
Committing a transaction makes that set of operations 'permanent' to the database. After committing it cannot be rolled back.
A rollback is when you reset the database to the state that existed prior to starting the transaction.
Below is an example of creating a transaction from an OleDbConnection object along with performing a commit and two cases where you may want to rollback:
using(OleDbConnection con = DAL.GetConnection())
{
OleDbTransaction transaction = null;
try
{
con.Open();
transaction = con.BeginTransaction()
string queryString1 = //SQL string
OleDbCommand cmd1 = new OleDbCommand();
{
Connection = con,
CommandType = CommandType.Text,
CommandText = queryString1
};
string queryString2 = //SQL string
OleDbCommand cmd2 = new OleDbCommand();
{
Connection = con,
CommandType = CommandType.Text,
CommandText = queryString2
};
int num1 = cmd.ExecuteNonQuery();
int num2 = cmd.ExecuteNonQuery();
if (num1 == 0 || num2 == 0)
{
//We didn't expect something to return 0, lets roll back
transaction.Rollback();
//send error message
Response.Redirect("register.aspx?err=Error");
}
else
{
//everything seems good, lets commit the transaction!
transaction.Commit();
Session["id"] = MyDB.GetUserId(uname);
Response.Redirect("home.aspx");
}
}
catch(OleDbException ex)
{
try
{
//something bad happened, lets roll everything back
transaction.Rollback();
Response.Redirect("register.aspx?err=Error");
}
catch
{
//we don't really care about this catch statement
}
}
}
Here's the MSDN article on the the OleDbConnection.BeginTransaction method with a generic example similar to what I posted above.
EDIT:
*As @Clockwork-Muse pointed out in the comments MySQL's ability to support transactions depends on the underlying engine being used. There are many MySQL engines, but the two main ones are InnoDB and MyISAM. InnoDB CAN support transactions, but MyISAM does NOT.
来源:https://stackoverflow.com/questions/30686261/how-do-i-do-many-sql-queries-as-transactions