如果多个语句中的任何其他语句失败,如何反转查询影响?
How do I reverse the query affect if any of the other statement fails among several statements?
var sqlCommand= "@ DELETE FROM table1 WHERE id = @Id
DELETE FROM table2 WHERE id = @Id ";
var isDeleted = db.Database
.ExecuteSqlCommand(sqlCommand, new SqlParameter("@Id", Id)) > 0;
问题是,如果第二个或任何其他语句失败,那么前面的语句将保持不变,即已被删除。
如果其中任何一个失败并且 return 错误,我希望它反转。
注意:必须按同样的方式进行,不能在存储过程中进行。
在 C# 中,您可以像这样使用 TransactionScope
:
using (TransactionScope t = new TransactionScope(TransactionScopeOption.Required))
{
//do your work
if(everything is ok)
t.Complete();
}
public void YourMethod(Sqlconnection conn,int id)
{
conn.Open();
using (SqlTransaction oTransaction = conn.BeginTransaction())
{
using (SqlCommand command = conn.CreateCommand())
{
string query =
"DELETE FROM table1 WHERE id=@Id;" +
"DELETE FROM table2 WHERE id=@Id;";
command.CommandText = query;
command.Parameters.Add(new SqlParameter("@Id", SqlDbType.Int));
command.Transaction = oTransaction;
command.CommandType = CommandType.Text;
try
{
command.Parameters[0].Value = id;
command.ExecuteNonQuery();
//start transaction
oTransaction.Commit();
}
catch (Exception)
{
//if the transaction fails then rollback the data
oTransaction.Rollback();
//notice the call method that there was an exception
throw;
}
finally
{
// Close connection
conn.Close();
}
}
}
}
EF 让这对您来说非常简单:
var isDeleted = db.Database.ExecuteSqlCommand(
TransactionalBehavior.EnsureTransaction, // <=== new
sqlCommand, new SqlParameter("@Id", Id)) > 0;
最好for many reasons 使用BEGIN TRAN
COMMIT
而不是使用客户端事务。确保有 XACT_ABORT ON
以防止出现异常时出现悬空事务
var sqlCommand= @"
SET XACT_ABORT ON;
BEGIN TRAN;
DELETE FROM table1 WHERE id = @Id;
DELETE FROM table2 WHERE id = @Id;
COMMIT TRAN;
";
var isDeleted = db.Database
.ExecuteSqlCommand(sqlCommand, new SqlParameter("@Id", Id)) > 0;
var sqlCommand= "@ DELETE FROM table1 WHERE id = @Id
DELETE FROM table2 WHERE id = @Id ";
var isDeleted = db.Database
.ExecuteSqlCommand(sqlCommand, new SqlParameter("@Id", Id)) > 0;
问题是,如果第二个或任何其他语句失败,那么前面的语句将保持不变,即已被删除。
如果其中任何一个失败并且 return 错误,我希望它反转。
注意:必须按同样的方式进行,不能在存储过程中进行。
在 C# 中,您可以像这样使用 TransactionScope
:
using (TransactionScope t = new TransactionScope(TransactionScopeOption.Required))
{
//do your work
if(everything is ok)
t.Complete();
}
public void YourMethod(Sqlconnection conn,int id)
{
conn.Open();
using (SqlTransaction oTransaction = conn.BeginTransaction())
{
using (SqlCommand command = conn.CreateCommand())
{
string query =
"DELETE FROM table1 WHERE id=@Id;" +
"DELETE FROM table2 WHERE id=@Id;";
command.CommandText = query;
command.Parameters.Add(new SqlParameter("@Id", SqlDbType.Int));
command.Transaction = oTransaction;
command.CommandType = CommandType.Text;
try
{
command.Parameters[0].Value = id;
command.ExecuteNonQuery();
//start transaction
oTransaction.Commit();
}
catch (Exception)
{
//if the transaction fails then rollback the data
oTransaction.Rollback();
//notice the call method that there was an exception
throw;
}
finally
{
// Close connection
conn.Close();
}
}
}
}
EF 让这对您来说非常简单:
var isDeleted = db.Database.ExecuteSqlCommand(
TransactionalBehavior.EnsureTransaction, // <=== new
sqlCommand, new SqlParameter("@Id", Id)) > 0;
最好for many reasons 使用BEGIN TRAN
COMMIT
而不是使用客户端事务。确保有 XACT_ABORT ON
以防止出现异常时出现悬空事务
var sqlCommand= @"
SET XACT_ABORT ON;
BEGIN TRAN;
DELETE FROM table1 WHERE id = @Id;
DELETE FROM table2 WHERE id = @Id;
COMMIT TRAN;
";
var isDeleted = db.Database
.ExecuteSqlCommand(sqlCommand, new SqlParameter("@Id", Id)) > 0;