回滚 SQL 事务(如果 C# 中有任何失败)
本文关键字:任何 失败 SQL 事务 如果 回滚 | 更新日期: 2023-09-27 18:32:45
我有一个Windows表单应用程序,只需单击一个按钮即可在数据库中执行一些sql脚本。这些 sql 脚本执行用户创建,并授予一些权限,如数据执行、数据读/写等。下面是执行此操作的示例 c# 代码:
script1 = "CREATE USER " + username + " FROM LOGIN " + username;
script2 = @"CREATE ROLE [db_execute] AUTHORIZATION [dbo]
GRANT EXECUTE TO [db_execute]";
script3 = @"DECLARE @rolename varchar(max)
SET @rolename ='{0}'
EXEC sp_addrolemember N'db_execute',@rolename
EXEC sp_addrolemember N'db_datareader', @rolename
EXEC sp_addrolemember N'db_datawriter', @rolename";
并在数据库中执行它,如下所示:
SqlCmd.CommandText = script1;
SqlCmd.Connection = oConnection;
var ans = SqlCmd.ExecuteNonQuery();
if (!ans.Equals(0))
{
//some task
} else
{
//messagebox
}
SqlCmd.CommandText = script2;
SqlCmd.Connection = oConnection;
var answer = SqlCmd.ExecuteNonQuery();
if (!answer.Equals(0))
{
//some task
} else
{
//messagebox
}
SqlCmd.CommandText = script3;
SqlCmd.Connection = oConnection;
var answ = SqlCmd.ExecuteNonQuery();
if (!answ.Equals(0))
{
//some task
} else
{
//messagebox
}
我通过按下按钮一次执行所有这些脚本,所以在我的理解中,我将其作为单个事务进行。我想做的是,如果这些脚本中的任何一个在两者之间失败,我应该能够在不做任何更改的情况下完全回滚。
为了给您一个更好的图片,如果 script3 的执行由于某种原因失败,它应该自动回滚 script1 和 script2 在数据库中所做的一切。
我们该怎么做呢?我用谷歌搜索了一下,发现了一些不相关的帖子。
任何帮助或想法将不胜感激。
使用 SqlConnection 和 SqlTransaction 对象。试试这个;
{
// declarations
try
{
// open connection
trans = conn.BeginTransaction();
cmd.Transaction = trans; // Includes this cmd as part of the trans
SqlCmd.CommandText = script1;
SqlCmd.Connection = oConnection;
var ans = SqlCmd.ExecuteNonQuery();
if (!answ.Equals(0))
{
//some task
} else
{
//messagebox
}
// Your other queries
trans.Commit(); // commit transaction
}
catch (Exception e){
trans.Rollback();
throw e;
}
finally{
conn.Close();
}
根据您的数据库系统,只有DML
(数据操作、选择/插入/更新/删除)可以是事务性的,因此可以回滚。 DDL
(数据定义,如 ALTER 或 CREATE)不能是事务的一部分。事实上,根据DBMS
,这些语句将在执行时隐式提交所有先前的DML语句。
如果需要事务(因为DBMS
不同或实际上具有 CRUD 语句),则需要在SqlConnection
上调用 BeginTransaction,并使用生成的对象提交或回滚。
我使用System.Transactions.TransactionScope,如果你把它括在access语句中,把你的代码放进去,然后使用scope.complete。
按照此 MSDN 参考中的说明使用 SqlTransaction 类
我建议在SQL中处理事务并将正确的消息返回给用户。原因是您有两个单独的层数据访问层 (DAL) 和 UI。
你可以在这里阅读更多关于 DAL 的信息
事务具有以下四个标准属性,通常由首字母缩略词 ACID 表示:
原子性:确保工作单元内的所有操作都成功完成;否则,事务将在故障点中止,并将以前的操作回滚到以前的状态。
一致性:确保数据库在成功提交事务时正确更改状态。
隔离:使事务能够独立运行且彼此透明。
持久性:确保在系统故障时,已提交事务的结果或效果仍然存在。
在此处阅读更多内容