【发布时间】:2013-10-21 11:10:58
【问题描述】:
如果我尝试创建现有表导致错误,则现有事务似乎已经自行回滚:
private void CreateSomeThings()
{
SqlConnection SqlConn = new SqlConnection(ConnectionString);
SqlConn.Open();
(new SqlCommand("BEGIN TRANSACTION", SqlConn)).ExecuteNonQuery();
try
{
(new SqlCommand("CREATE TABLE sometable ([some_id] [int] IDENTITY(1,1) NOT NULL)", SqlConn)).ExecuteNonQuery();
// Create the table again, but carry on by catching the exception
try
{
(new SqlCommand("CREATE TABLE sometable ([some_id] [int] IDENTITY(1,1) NOT NULL)", SqlConn)).ExecuteNonQuery();
}
catch (Exception)
{
}
// If another exception is thrown
(new SqlCommand("bingy bongy boo", SqlConn)).ExecuteNonQuery();
(new SqlCommand("COMMIT TRANSACTION", SqlConn)).ExecuteNonQuery();
}
catch (Exception Ex)
{
try
{
// ... then this command will fail with "no corresponding BEGIN TRANSACTION"
(new SqlCommand("ROLLBACK TRANSACTION", SqlConn)).ExecuteNonQuery();
}
catch (Exception Ex2)
{
throw;
}
}
}
我想了解发生了什么以及为什么。我希望事务回滚是我的责任 - 对于其他错误,它不会这样做:例如,如果我只是调用“bingy bongy”,则只有调用会引发异常,然后我在异常中 ROLLBACK 没有任何问题。
【问题讨论】:
-
你怎么知道的?究竟是什么问题?
-
请看代码cmets。
ROLLBACK TRANSACTION在异常处理程序中失败。 -
问题是“我不明白”,我想了解发生了什么以及为什么。我希望事务回滚是我的责任 - 对于其他错误,它不会为我这样做。
-
您在此处的每个查询都是单独的事务,因此您的回滚不会起作用。您需要使用事务对象或更通用的函数在 BEGIN/ROLLBACK/COMMIT 事务中使用 errorraise() 和错误捕获 SQL SIDE 包装事务 SQL。
-
可能是这样,但是如果我将代码更改为使用事务对象,我会遇到同样的问题:如果您尝试创建一个已经存在的表,则事务对象将被关闭/回滚代表我。如果我犯了一些其他错误(例如调用
bingy bongy boo),事务仍然有效,我现在负责回滚。对我来说似乎不太一致。
标签: c# sql-server transactions sqltransaction