如果故障回滾到以前的保存點(而不是回滾整個事務),是否有任何方法在事務和中添加檢查約束? ?在發生故障時將事務回滾到保存點ALTER TABLE ... ADD CONSTRAINT
在我的情況下,當ALTER TABLE ... ADD CONSTRAINT命令失敗時,事務不能回滾到保存點(嘗試這樣做會引發InvalidOperationException)。
概述演示的關鍵點:
SqlTransaction transaction = connection.BeginTransaction();
// ... execute SQL commands on the transaction ...
// Create savepoint
transaction.Save("mySavepoint");
try
{
// This will fail...
SqlCommand boom = new SqlCommand(
"ALTER TABLE table WITH CHECK ADD CONSTRAINT ...",
connection,
transaction);
boom.ExecuteNonQuery();
}
catch
{
// ...and should be rolled back to the savepoint, but can't.
try
{
transaction.Rollback("mySavepoint");
}
catch (InvalidOperationException)
{
// Instead, an InvalidOperationException is thrown.
// The transaction is unusable and can only be rolled back entirely.
transaction.Rollback();
}
}
而這裏的現成運行演示代碼來測試(你需要一個名爲datase「測試」):
public class Demo
{
private const string _connectionString = "Data Source=(local);Integrated security=true;Initial Catalog=test;";
private const string _savepoint = "save";
private static readonly string _tableName = DateTime.Now.ToString("hhmmss");
private static readonly string _constraintName = "CK" + DateTime.Now.ToString("hhmmss");
private static readonly string _createTable = "CREATE TABLE [dbo].[" + _tableName + "] ([one] [int] NULL,[two] [int] NULL) ON [PRIMARY]";
private static readonly string _insert1 = "INSERT INTO [" + _tableName + "] VALUES (1,1)";
private static readonly string _addConstraint = "ALTER TABLE [dbo].[" + _tableName + "] WITH CHECK ADD CONSTRAINT [" + _constraintName + "] CHECK (([one]>(1)))";
private static readonly string _insert2 = "INSERT INTO [" + _tableName + "] VALUES (2,2)";
public static void Main(string[] args)
{
// Example code! Please ignore missing using statements.
SqlConnection connection = new SqlConnection(_connectionString);
connection.Open();
SqlTransaction transaction = connection.BeginTransaction();
SqlCommand createTable = new SqlCommand(_createTable, connection, transaction);
createTable.ExecuteNonQuery();
// Create savepoint
transaction.Save(_savepoint);
SqlCommand insert1 = new SqlCommand(_insert1, connection, transaction);
insert1.ExecuteNonQuery();
try
{
// This will fail...
SqlCommand boom = new SqlCommand(_addConstraint, connection, transaction);
boom.ExecuteNonQuery();
}
catch
{
// ...and should be rolled back to the savepoint, but can't
transaction.Rollback(_savepoint);
}
SqlCommand insert2 = new SqlCommand(_insert2, connection, transaction);
insert2.ExecuteNonQuery();
transaction.Commit();
connection.Close();
}
}
當我純粹在TSQL中嘗試時,出現錯誤「當前事務不能被提交併且不能被回滾到保存點,回滾整個事務。」 - 只要看看註定的交易。 – 2011-03-15 16:35:58
沒有找到任何明確說明哪些錯誤導致事務被中止(或呈現爲不可承諾)的文檔,但是顯然這個錯誤似乎是其中的一個! – 2011-03-15 17:07:04
事實上,缺乏關於該主題的具體文檔幾乎同樣令人討厭。 – nodots 2011-03-15 20:27:16