Отличается ли Connection.BeginTransaction() от начала транзакции SQL?

Сегодня кто-то сказал, что C# connection.BeginTransaction() отличается от T-SQL begin transaction, поэтому я проверил его, и результат оказался правдой.

Код C# с использованием connection.BeginTransaction():

using (var connection = Connection)
{
    connection.Open();
    var cmd = connection.CreateCommand();
    cmd.CommandText = "create table #TransactionTest ([ID] int);";
    cmd.ExecuteNonQuery();
    cmd.CommandText = "insert into #TransactionTest ([ID]) values (1);";
    cmd.ExecuteNonQuery();

    using (var transaction = connection.BeginTransaction())
    {
        cmd.CommandText = "insert into #TransactionTest ([ID]) values (1);";
        cmd.Transaction = transaction;
        cmd.ExecuteNonQuery();

        transaction.Rollback();
    }

    cmd.CommandText = "select count(1) from #TransactionTest";
    var count = cmd.ExecuteScalar(); //result : 0 count
}

Код C# с использованием T-SQL Begin Transaction:

using (var connection = Connection)
{
    connection.Open();
    var cmd = connection.CreateCommand();
    cmd.CommandText = "create table #TransactionTest ([ID] int);";
    cmd.ExecuteNonQuery();
    cmd.CommandText = "insert into #TransactionTest ([ID]) values (1);";
    cmd.ExecuteNonQuery();

    cmd.CommandText = "begin transaction;";
    cmd.ExecuteNonQuery();
    cmd.CommandText = "insert into #TransactionTest ([ID]) values (1);";
    cmd.ExecuteNonQuery();
    cmd.CommandText = "rollback;";
    cmd.ExecuteNonQuery();

    cmd.CommandText = "select count(1) from #TransactionTest";
    var count = cmd.ExecuteScalar(); //result : 0 count
}

На мой взгляд, эта логика эквивалентна следующему SQL:

create table #TransactionTest ([ID] int, [Value] varchar(32));

begin transaction;
    insert into #TransactionTest ([ID], [Value]) 
    values (1, 'ABC');

    rollback transaction ;

    insert into #TransactionTest ([ID]) 
    values (1); 

    select * from #TransactionTest; 

Я не обнаружил действия по началу транзакции с помощью настройки SQL Server Profiler с помощью C# connection.BeginTransaction

Отличается ли Connection.BeginTransaction() от начала транзакции SQL?

но нашел С# sql BeginTransaction Отличается ли Connection.BeginTransaction() от начала транзакции SQL?

Вопрос:

Это реально или просто скрыто из базы данных?

Конфигурация по умолчанию для SQL Profiler не отображает транзакции. Я бы посмотрел на это.

Stephen Wrighton 17.03.2019 16:49

Я выбираю шаблон настройки SQL Profiler @Stephen Wrighton, я ищу в Google профайлер перевода.

Wei Lin 17.03.2019 16:50

вам нужно будет отметить «показать все события» и создать новый шаблон профиля. вот ссылка: weblogs.asp.net/dixin/…

Stephen Wrighton 17.03.2019 16:54

Просто добавьте события Transaction непосредственно в трассировку в группе Transaction в Profiler. Обратите внимание, что клиентские API могут управлять транзакциями напрямую по протоколу TDS, поэтому оператор T-SQL не выполняется.

Dan Guzman 17.03.2019 16:55

спасибо @Stephen Wrighton, вы можете ответить ниже, это ответ

Wei Lin 17.03.2019 16:56

Спасибо. Я вижу, соединение С#.

Wei Lin 17.03.2019 17:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
737
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Существуют значительные различия из-за того, как транзакции реализованы в .NET, хотя во многих случаях (например, в вашем примере) они действуют одинаково.

  • Транзакции в SQL Server будут автоматически продвигаться по мере необходимости. Транзакций ADO.NET не будет.
  • ADO.NET не допустит параллельного транзакций, даже если включено несколько наборов результатов.
  • АДО.НЕТ транзакции привязаны к объекту Connection, что видно из код, но легко сбивает людей с толку:
var transaction = connection.BeginTransaction()
  • Почему это сбивает с толку? Поскольку объекты Command привязаны к соединению также, но транзакция в соединении не приравнивается к транзакции в его объектах Command.
    • Пример: возьмите свое соединение, в котором запущена транзакция, создайте с ним новую команду и попытайтесь выполнить. Это не удастся, если вы явно не предоставите транзакцию новому объекту Command.

Что касается передовой практики, я обнаружил, что верно следующее:

  • Хранимые процедуры — лучший способ избежать проблем, когда необходимы транзакции.
  • Следует избегать использования DDL (даже для временных таблиц) в транзакции. SQL Server позволит это сделать, а другие базы данных, такие как Oracle, — нет.

Вы можете прочитать больше об этом в документации MS здесь.

Другие вопросы по теме