#sql-server #database #sql-server-2008 #tsql #transactions
#sql-сервер #База данных #sql-server-2008 #tsql #транзакции
Вопрос:
Я пытаюсь реализовать автономную транзакцию в процедуре SQL Server 2008. Процедура будет просто иметь две вложенные транзакции, на которые InnerTransaction
будет совершена фиксация, но OuterTransaction
будет выполнен откат. Я видел много примеров, которые успешно реализуют обратные процессы. Но я не нашел никакого решения для своей проблемы.
примеры сценариев таблиц
create table testTab1(id int identity(1,1) primary key, name varchar(100));
create table testTab2(id int , name varchar(100));
insert into testTab1(name) values('User1'),('User2'),('User3');
пример кода procudure
CREATE PROCEDURE [dbo].[testSP2]
AS
BEGIN
SET IMPLICIT_TRANSACTIONS ON
BEGIN TRAN
insert into testTab1(name) values('User4'),('User5'),('User6');
IF @@ROWCOUNT>0
BEGIN
SAVE TRAN InnerTran
insert into testTab2(id,name) values(1,'User4'),(2,'User5'),(3,'User6');
--PRINT 'NUMBER OF TRAN=' CAST(@@TRANCOUNT AS VARCHAR(5))
COMMIT TRAN InnerTran
END
ROLLBACK
SET IMPLICIT_TRANSACTIONS OFF
END
МОЙ желаемый результат
Комментарии:
1. Проще говоря … вы не можете. Вложенные транзакции — это миф. Они даже близко не подходят к тому, что, по вашему мнению, они должны. Вторая транзакция только увеличивает значение @@TRANCOUNT, а откат или фиксация устанавливает счетчик равным 0 и выполняет откат / фиксацию для каждой «вложенной» транзакции. sqlskills.com/blogs/paul /…
2. @SeanLange спасибо за ваш комментарий, я просто хочу быть уверен, что сможем ли мы сделать это на Sql server или не будем использовать
nested transaction
. Но я думаю, что теперь мне нужно использовать другой подход, чтобы сделать это. можете ли вы предложить какой-нибудь хак для этого?3. Как я уже говорил ранее, сделать это невозможно. Точка. Конец истории. Однако реальная проблема заключается в ТОМ, ЧТО вы на самом деле пытаетесь сделать, потому что, скорее всего, вам просто нужно подумать об этом по-другому. Возможно, вам нужно использовать TRY / CATCH. Затем, если ваша вставка завершается неудачно, вы используете catch для вставки в другое место.
4. У Oracle, конечно, есть эта функция, и она называется автономной транзакцией. Я работаю в мире SQL Server всего 1,5 года, и меня бесит, что автономной транзакции не существует. Эта функция активно использовалась моим кодом и другими членами моей команды, когда я работал в Oracle более 8 лет. Так раздражает, когда вы обнаруживаете что-то настолько простое (в концепции), что вы так долго использовали, но вы обнаруживаете, что другие очень похожие технологии не реализуют эти функции, которые вы принимаете как должное.
5. Я просто наблюдаю и жду, когда Microsoft предоставит нам функцию автономной транзакции, благодаря которой я оказался в этом посте SO. Я просматриваю это, возможно, раз в месяц.
Ответ №1:
Еще один блог, но хорошо написанный, показывающий каждый «взлом», чтобы имитировать замечательную функцию автономной транзакции Oracle. Я с нетерпением жду мира, в котором эта функция существует в SQL Server.
Примечание: По какой-то причине, когда вы доводите это до сведения пользователей SQL Server, они смотрят на вас как на сумасшедшего и начинают спрашивать что-то вроде «Зачем вам это нужно… зачем кому-либо это нужно?». Теперь, когда я нахожусь в магазине SQL Server, я получаю это тонну. Просто знайте, что если вы пришли из Oracle … база данных, которая обладает надежными и глубокими функциями, такими как встроенные алгоритмы поиска и отличные возможности синтаксического анализа строк и манипулирования ими, вы обнаружите после погружения в SQL Server, что в ней отсутствуют эти функции. Не поймите меня неправильно… SQL Server очень хорошо выполняет многие функции, такие как табличные переменные и временные таблицы, а также просто возможность смешивать ваш T-SQL в соответствии с обычным SQL. Oracle отделяет свой PL-SQL от своего SQL Engine, и это один из основных недостатков Oracle. За и против.
Комментарии:
1. Хотя я когда-либо работал только с SQL Server, а не с Oracle, варианты использования автономных транзакций возникают каждый год или два. Это была бы действительно удобная функция. Для меня основным вариантом использования является запись в таблицу журнала независимо от результата транзакции. Если мы полностью контролируем транзакции, мы могли бы использовать переменные или табличные переменные (которые не зарегистрированы в транзакции) для хранения данных, которые мы хотим зарегистрировать, и регистрировать их после отката транзакции (или фиксации). Но иногда хранимый процесс регистрируется во внешней транзакции и все еще нуждается в регистрации сообщений.