Поделиться через


Ошибка "Недопустимая транзакция", если почта базы данных не может отправить сообщение в SQL Server

Эта статья поможет устранить проблему, из-за которой почта базы данных не отправляет сообщение.

Исходная версия продукта: SQL Server 2012, SQL Server 2014, SQL Server 2016, SQL Server 2017 в Linux, SQL Server 2017 в Windows
Исходный номер базы знаний: 4502457

Симптомы

Предположим, что пользователь, работающий под управлением Microsoft SQL Server, не может отправлять компонент Database Mail. В этом случае в журнале почты базы данных (sysmail_event_log) показана следующая запись:

Сведения об исключении: тип исключения: Microsoft.SqlServer.Management.SqlIMail.Server.Common.BaseException
Сообщение: транзакция больше не действительна.
Данные: System.Collections.ListDictionaryInternal
TargetSite: Void ValidateConnectionAndTransaction()
HelpLink: NULL
Источник: DatabaseMailEngine
Сведения StackTrace: на сайте Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.ConnectionManager.ValidateConnectionAndTransaction()
на сайте Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.ConnectionManager.RollbackTransaction()
на сайте Microsoft.SqlServer.Management.SqlIMail.IMailProcess.QueueItemProcesser.GetDataFromQueue(DataAccessAdapter da, Int32 lifetimeMinimumSec)
at Microsoft.SqlServer.Management.SqlIMail.IMailProcess.QueueItemProcesser.ProcessQueueItems(String dbName, String dbServerName, Int32 lifetimeMinimumSec, LogLevel loggingLevel, Byte[] encryptionKey, Int32 connectionTimeout)',@proc

Примечание.

  • Фраза больше недействительна в поле "Сообщение " означает, что транзакция больше не действительна.
  • В журнале приложений может отображаться то же сообщение. Почтовое сообщение останется в состоянии sysmail_unsentitemsповтора и останется неотступным до тех пор, пока DatabaseMail.exe внешняя программа не будет успешно запущена.

Причина

Параметр подключения по умолчанию SQL Server использует set NUMERIC_ARITHABORT ON. При запуске sp_send_dbmailсообщение электронной почты помещается в очередь в ExternalMailQueue. При появлении сообщения в очереди хранимая процедура активации активирует DatabaseMail.exe внешний исполняемый файл. При подключении DatabaseMail.exe к SQL Server он выполняется sp_readrequest для чтения сообщений из очереди. Во время выполнения sp_readrequestвы можете заметить, что возникает исключение. SELECT Следующая инструкция выполняется в sp_readrequest (для просмотра этой SELECT инструкции необходимо собрать трассировку на уровне инструкции):

DatabaseMail - DatabaseMail - Id\<ProcessId>        \<NTUserName>        \<SPID>                \<StartTime>              msdb        \<LoginSid>  \<SessionLoginName>
-- network protocol: TCP/IP
set quoted_identifier on
set arithabort off
set numeric_roundabort on
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed
2 - Pooled        1        1 - Non-DAC
RPC:Starting <BinaryData> 4 <NTUserName> DatabaseMail - DatabaseMail - Id<ProcessId> <NTUserName> <SPID> <StartTime> sp_readrequest msdb <LoginSid> <SessionLoginName> exec sp_readrequest @receive_timeout=600000

SP:StmtStarting <BinaryData> 4 <NTUserName> DatabaseMail - DatabaseMail - Id<ProcessId> <NTUserName> <SPID> <StartTime> sp_readrequest msdb <LoginSid> <SessionLoginName>

SELECT @mailitem_id = MailRequest.Properties.value('(MailItemId)[1]', 'int')  
FROM @xmlblob.nodes('
declare namespace requests="https://schemas.microsoft.com/databasemail/requests]";/requests:SendMail')

AS MailRequest(Properties)
If SET NUMERIC_ARITHABORT ON is set as default connection option, this SELECT statement will encounter error 1934 and an exception will occur:

Exception 4 <servername> DatabaseMail - DatabaseMail - Id<ProcessId> <NTUserName> <SPID> <StartTime> 1934 msdb <LoginSid> <SessionLoginName> SELECT failed because the following SET options have incorrect settings:  
'NUMERIC_ROUNDABORT'.  
Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatialindex operations.

Когда DatabaseMail.exe встречает исключение, откат выполняется, но завершается сбоем. Исключение приводит к тому, что транзакция выходит из области. По этой причине транзакция больше недействителен в журнале Database Mail.

Однако основная причина проблемы заключается в том, что ошибка 1934 возникает из-за несовместимого параметра SET , когда метод типа данных XML (MailRequest.Properties.value('(MailItemId)[1]', 'int')) используется в инструкции SELECT .

Проверка сообщения об ошибке

  • Проверьте, является ли сообщение об ошибке в журнале Database Mail одинаковым сообщением (транзакция больше не действительна).

  • Сбор трассировки профилировщика путем включения событий уровня инструкций, ошибок и предупреждений и событий брокера.

  • Проверьте параметр экземпляра SQL Server для параметров подключения по умолчанию. Для этого откройте SQL Server Management Studio, щелкните правой кнопкой мыши сервер и выберите параметры>подключения по>умолчанию свойств>по умолчанию.

Решение

Чтобы устранить эту проблему, измените параметр подключения по умолчанию на SET NUMERIC_ROUNDABORT OFF.