If you’re receiving error Msg 3902, Level 16, which reads “The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION”, it’s probably because you’ve got a stray COMMIT statement.
You could be getting this due to implementing error handling, and forgetting that you’ve already committed or rolled back the transaction elsewhere in your code.
Example of Error
Here’s a simple example to demonstrate the error:
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
Result:
(7 rows affected) Msg 3902, Level 16, State 1, Line 2 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
This will occur if your SET IMPLICIT_TRANSACTIONS is OFF. See below for what happens when SET IMPLICIT_TRANSACTIONS is ON.
Example of Error due to Error Handling
You could be getting this due to implementing error handling, and forgetting that you’ve already committed or rolled back the transaction elsewhere in your code.
For example:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Orders ( OrderId, OrderDate, CustomerId )
VALUES ( 5006, SYSDATETIME(), 1006 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 1, 1, 20, 25.99 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 2, 7, 120, 9.99 );
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
COMMIT TRANSACTION;
Result:
(1 row affected) (1 row affected) (1 row affected) Msg 3902, Level 16, State 1, Line 20 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
In this case, I already had COMMIT TRANSACTION in the TRY block. So by the time the second COMMIT TRANSACTION was encountered, the transaction had already been committed.
We would see the same even if the transaction had encountered an error, and was rolled back. A rollback will end the transaction, and therefore, no further COMMIT statements are required.
So to fix this issue, we’d simply remove the last COMMIT TRANSACTION, and the transaction code would look like this:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Orders ( OrderId, OrderDate, CustomerId )
VALUES ( 5006, SYSDATETIME(), 1006 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 1, 1, 20, 25.99 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 2, 7, 120, 9.99 );
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
Implicit Transactions
If you have implicit transactions enabled, you might get different results to the first example.
If we set IMPLICIT_TRANSACTIONS to ON, here’s what we get:
SET IMPLICIT_TRANSACTIONS ON;
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
Result:
+---------------------------------+----------------+ | ProductName | ProductPrice | |---------------------------------+----------------| | Left handed screwdriver | 25.99 | | Long Weight (blue) | 14.75 | | Long Weight (green) | 11.99 | | Sledge Hammer | 33.49 | | Chainsaw | 245.00 | | Straw Dog Box | 55.99 | | Bottomless Coffee Mugs (4 Pack) | 9.99 | +---------------------------------+----------------+ (7 rows affected)
No error occurs.
This is because, certain T-SQL statements automatically start a transaction when they run. It’s as if they were preceded by an invisible BEGIN TRANSACTION statement.
When IMPLICIT_TRANSACTIONS is OFF, these statements are automatically committed. It’s as if they’re succeeded by an invisible COMMIT TRANSACTION statement. In this scenario, the transaction is in autocommit mode.
When IMPLICIT_TRANSACTIONS is ON, there is no invisible COMMIT TRANSACTION statement. These statements are still started by an invisible BEGIN TRANSACTION, but they need to be ended explicitly.
An implicit transaction remains in progress until it is either explicitly committed or explicitly rolled back.
Therefore, in this example, our stray COMMIT TRANSACTION statement was actually needed to end the implicit transaction.
Вероятно вы на версии платформы 8.2.13 обновили конфигурацию БП на версию 2.0.42.5, после чего при обновлении платформы на версию 8.2.16.368 или выше при запуске базы после конвертации происходит ошибка SDBL.
Способ обхода сначала обновить платформу, сконвертировать ИБ, и только после этого обновляться на 2.0.42
Если обновление конфигурации на 2.0.42.5 выполнялось на 8.2.13, то режим совместимости оказался с 8.2.16, а изменения структуры таблиц БД, которую сделала бы 8.2.16 при смене режима совместимости, не произошло, т.к. 13-й релиз этого не умеет. Таким образом, если далее запускается платформа 16-го релиза, то она считает, что изменение структуры таблиц уже выполнено, хотя этого не произошло. Это и приводит к описанному эффекту. Как обойти: сначала обновить платформу, сконвертировать ИБ, и только после этого обновляться на 2.0.42; либо 1. Открыть 13-м релизом Конфигуратора 2. Сохранить конфигурацию в файл 3. понизить режим совместимости до 8.1, реструктуризовать 4. установить режим совместимости «Не используется», реструктуризовать 5. Закрыть Конфигуратор 13-го релиза, открыть Конфигуратор 16-го. 6. Выполнить загрузку конфигурации из файла, реструктуризоваться.
I’ve been using this library for a long time on a database with compatibility level 100, and I just recently connected to another one with compatibility level 140. It’s this one that’s giving me trouble:
FactoryBot.create(:calendar)
AppointmentStatus Load (0.6ms) EXEC sp_executesql N'SELECT TOP 1 [appointment_status].* FROM [appointment_status] WHERE [appointment_status].[name] = @0 ORDER BY [appointment_status].[id] ASC ', N'@0 varchar(35), @1 int', @0 = 'Open', @1 = 1 [["name", "Open"], ["LIMIT", 1]]
SQL (0.3ms) BEGIN TRANSACTION
SQL (0.5ms) select newid()
(1.2ms) select newid()
Calendar Exists (0.5ms) EXEC sp_executesql N'SELECT TOP 1 1 AS one FROM [calendar] WHERE [calendar].[id] = @0 ORDER BY [calendar].[id] ASC ', N'@0 uniqueidentifier, @1 int', @0 = '5B0B8280-6237-4791-A023-A7989E9634DF', @1 = 1 [["id", "5B0B8280-6237-4791-A023-A7989E9634DF"], ["LIMIT", 1]]
SQL (1.9ms) EXEC sp_executesql N'INSERT INTO [calendar] ([id], [start_date], [stop_date], [short_notes], [subject], [appointmentstatusid], [date_modified], [staff]) VALUES (@0, @1, @2, @3, @4, @5, @6, @7)', N'@0 uniqueidentifier, @1 datetime2(7), @2 datetime2(7), @3 varchar(1000), @4 varchar(255), @5 uniqueidentifier, @6 datetime2(7), @7 varchar(max)', @0 = '5B0B8280-6237-4791-A023-A7989E9634DF', @1 = '04-09-2020 15:37:39.0', @2 = '04-09-2020 12:22:39.0', @3 = 'Optio dolores ab. Exercitationem eos veniam. Maiores nostrum voluptate.', @4 = 'Subject', @5 = 'D0BF3A9C-BA9C-4A45-8B30-A98500A81501', @6 = '04-09-2020 19:54:39.4235502', @7 = '8CFFF4E7-CBEE-4E44-8431-61170E4CD108' [["id", "5B0B8280-6237-4791-A023-A7989E9634DF"], ["start_date", "04-09-2020 15:37:39.0"], ["stop_date", "04-09-2020 12:22:39.0"], ["short_notes", "Optio dolores ab. Exercitationem eos veniam. Maiores nostrum voluptate."], ["subject", "Subject"], ["appointmentstatusid", "D0BF3A9C-BA9C-4A45-8B30-A98500A81501"], ["date_modified", "04-09-2020 19:54:39.4235502"], ["staff", "8CFFF4E7-CBEE-4E44-8431-61170E4CD108"]]
SQL (0.7ms) COMMIT TRANSACTION
ActiveRecord::StatementInvalid (TinyTds::Error: The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.: COMMIT TRANSACTION)
The sql looks fine to me, so I’m not sure what to think. I’m using gem version 5.0.8 because due to other limitations I can’t upgrade this project beyond Rails 5.0. I tried ignoring that and upgrading to Rails 5.1 and upgrading this gem to the equivalent 5.1.# version but I still get the same error.
I actually have my test database in a container on dockerhub, but I’m not sure the best way to create a test app to reproduce this for you. Is there a base you all prefer to build off of for repro tests?
Ошибка СУБД
Модератор: Дмитрий Юхтимовский
Ошибка СУБД
Ошибка СУБД: Microsoft SQL Server Native Client 11.0: Запрос COMMIT TRANSACTION не имеет соответствующей инструкции BEGIN TRANSACTION. HRESULT=80004005, SQLSrvr: SQLSTATE=25000, state=1, Severity=10, native=3902, line=1
Добрый день, не знаю можно ли здесь обращаться с подобными вопросами, но если можно, то столкнулся с такой ошибкой, она возникает при установке ролей пользователю, возникает не всегда, а когда либо много пользователей работает, либо запущены все регламентные задания.
Подскажите пожалуйста куда копать.
- Антон
- Сообщений: 4
- Зарегистрирован: 18 июн 2015, 21:41
Re: Ошибка СУБД
Гилёв Вячеслав » 18 июн 2015, 23:27
откатиться к предыдущей версии конфигурации
- Гилёв Вячеслав
- Сообщений: 2791
- Зарегистрирован: 11 фев 2013, 15:40
- Откуда: Россия, Москва
Re: Ошибка СУБД
Антон » 19 июн 2015, 11:16
Вы не про уровень совместимости?
именно про наши доработки?
- Антон
- Сообщений: 4
- Зарегистрирован: 18 июн 2015, 21:41
Re: Ошибка СУБД
Антон » 19 июн 2015, 11:19
такое ощущение, что перед этим уровень совместимости повысили.
- Антон
- Сообщений: 4
- Зарегистрирован: 18 июн 2015, 21:41
Re: Ошибка СУБД
Антон » 19 июн 2015, 11:55
вообще ради интереса, поставил на локальную машину sql server, взял вчерашний бекап, зашел под 10 пользователями, включил все регламентные задания, стал менять права пользователям, все работает.
(при таких же условия и даже меньших пользователях не всегда дает менять права)
единственные отличия на глаз это операционные системы, на локальной машине 7 стоит, на сервере с проблемами 2008 R2.
И на локальной платформа последняя, на сервере предпоследняя, но не думаю что дело в этом. (хотя этот нюанс проверю в выходные.)
- Антон
- Сообщений: 4
- Зарегистрирован: 18 июн 2015, 21:41
Re: Ошибка СУБД
Гилёв Вячеслав » 19 июн 2015, 12:59
я про предыдущую версию кода конфигурации
- Гилёв Вячеслав
- Сообщений: 2791
- Зарегистрирован: 11 фев 2013, 15:40
- Откуда: Россия, Москва
Вернуться в MS SQL Server для целей 1С:Предприятие
Кто сейчас на форуме
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1
On Transact SQL language the Msg 3902 Level 16 — The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION means that the command begin tranasaction is missing.
Msg 3902 Level 16 Example:
Invalid TRANSACTION
USE tempdb;
GO
INSERT INTO dbo.departments (ID, NAME) VALUES (10, N'd1');
INSERT INTO dbo.departments (ID, NAME) VALUES (20, N'd2');
INSERT INTO dbo.departments (ID, NAME) VALUES (30, N'd3');
INSERT INTO dbo.departments (ID, NAME) VALUES (40, N'd4');
GO
COMMIT WORK;
GO
| Message |
|---|
| Msg 3902, Level 16, State 1, Line 8 |
| The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION. |
Correct TRANSACTION:
USE tempdb;
GO
BEGIN TRANSACTION;
GO
INSERT INTO dbo.departments (ID, NAME) VALUES (10, N'd1');
INSERT INTO dbo.departments (ID, NAME) VALUES (20, N'd2');
INSERT INTO dbo.departments (ID, NAME) VALUES (30, N'd3');
INSERT INTO dbo.departments (ID, NAME) VALUES (40, N'd4');
GO
COMMIT WORK;
GO
Other error messages:
- Specified scale is invalid
- The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name
- Table already has a primary key defined on it
- Column name does not exist in the target table or view
- Violation of PRIMARY KEY constraint
- Column names in each table must be unique
- There is already an object named in the database
