Как включить вложенные транзакции с ADO.NET и SQL Server? - PullRequest
7 голосов
/ 18 мая 2010

У меня есть вопрос, аналогичный , как проверить , если вы находитесь в транзакции . Вместо того, чтобы проверять, как разрешить вложенные транзакции?

Я использую базу данных Microsoft SQL Server с ADO.NET. Я видел примеры использования T-SQL и примеры запуска транзакций с использованием начала и использования имен транзакций. При вызове connection.BeginTransaction я вызываю другую функцию в том же соединении, и она снова вызывает BeginTransaction, что дает мне исключение:

SqlConnection does not support parallel transactions.

Похоже, многие варианты Microsoft позволяют это, но я не могу понять, как это сделать с моим файлом .mdf.

Как разрешить вложенные транзакции с базой данных Microsoft SQL Server с использованием C # и ADO.NET?

Ответы [ 3 ]

7 голосов
/ 19 мая 2010

SQL Server в целом не поддерживает вложенные транзакции. В T-SQL вы можете выдать BEGIN TRAN внутри более ранней BEGIN TRAN, но это только для удобства. Это только внешняя транзакция, которая имеет значение. Клиент .NET для SQL Server (SqlConnection) даже не позволяет вам сделать это и выдает это исключение при попытке.

3 голосов
/ 07 декабря 2012

Это распространенное заблуждение, что SQL Server поддерживает вложенные транзакции. Это не. открытие нескольких транзакций и последующий вызов commit абсолютно ничего не делает. Вы можете легко написать тестовый SQL, чтобы попробовать это самостоятельно. Единственный вариант для эмуляции вложенной транзакции - это использование точек сохранения.

Я должен добавить, что единственное, что имеет значение, - это когда @@ TRAN_COUNT достигает нуля, это точка, в которой будет совершена только внешняя транзакция.

1 голос
/ 08 июня 2012
SqlConnection conn = new SqlConnection(@"Data Source=test;Initial Catalog=test;User ID=usr;Password=pass");
conn.Open();
var com = conn.CreateCommand();

com.CommandText = "BEGIN TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "BEGIN TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "INSERT INTO testTable (ParamName,ParamValue) values ('test','test');";
com.ExecuteNonQuery();
com.CommandText = "COMMIT TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "ROlLBACK TRANSACTION";
com.ExecuteNonQuery();

com.CommandText = "SELECT COUNT(*) FROM testTable ";

MessageBox.Show(string.Format("Found {0} rows.", com.ExecuteScalar()));
...