Condividi tramite


Errore "La transazione non più valida" quando la posta elettronica del database non riesce a inviare un messaggio in SQL Server

Questo articolo consente di risolvere il problema in cui posta elettronica database non riesce a inviare un messaggio.

Versione originale del prodotto: SQL Server 2012, SQL Server 2014, SQL Server 2016, SQL Server 2017 in Linux, SQL Server 2017 in Windows
Numero KB originale: 4502457

Sintomi

Si supponga che un utente che esegue Microsoft SQL Server non possa inviare Posta elettronica database. In questo caso, il log di Posta elettronica database (sysmail_event_log) mostra la voce seguente:

Informazioni sull'eccezione: Tipo di eccezione: Microsoft.SqlServer.Management.SqlIMail.Server.Common.BaseException
Messaggio: transazione non più valida.
Dati: System.Collections.ListDictionaryInternal
TargetSite: Void ValidateConnectionAndTransaction()
HelpLink: NULL
Origine: DatabaseMailEngine
Informazioni su StackTrace: in Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.ConnectionManager.ValidateConnectionAndTransaction()
in Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.ConnectionManager.RollbackTransaction()
in 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

Note

  • La frase non più valida viene visualizzata in questo modo nel campo Messaggio per indicare che la transazione non è più valida.
  • È possibile che venga visualizzato lo stesso messaggio nel registro applicazioni. Il messaggio di posta elettronica rimarrà nello stato di "ripetizione dei tentativi" in sysmail_unsentitemse rimarrà non inviato fino a quando il programma esterno DatabaseMail.exe può essere eseguito correttamente.

Causa

L'opzione di connessione predefinita di SQL Server usa SET NUMERIC_ARITHABORT ON. Quando si esegue sp_send_dbmail, il messaggio di posta elettronica viene accodato a ExternalMailQueue. Quando viene visualizzato un messaggio nella coda, la stored procedure di attivazione attiva il DatabaseMail.exe eseguibile esterno. Quando DatabaseMail.exe è connesso a SQL Server, viene eseguito sp_readrequest per leggere i messaggi dalla coda. Durante l'esecuzione di sp_readrequest, è possibile notare che si verifica l'eccezione. L'istruzione seguente SELECT viene eseguita in sp_readrequest (è necessario raccogliere la traccia a livello di istruzione per visualizzare questa SELECT istruzione):

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.

Quando DatabaseMail.exe rileva l'eccezione, viene eseguito un tentativo di rollback ma non riesce. L'eccezione causa l'uscita dall'ambito della transazione. Per questo motivo, un messaggio non più valido viene registrato nel log di Posta elettronica database.

Tuttavia, la causa radice del problema è che l'errore 1934 si verifica a causa di un'opzione SET incompatibile quando viene usato il metodo del tipo di dati XML (MailRequest.Properties.value('(MailItemId)[1]', 'int')) nell'istruzione SELECT .

Verificare il messaggio di errore

  • Controllare se il messaggio di errore nel log di Posta elettronica database è lo stesso messaggio (Transazione non più valida).

  • Raccogliere una traccia del profiler con eventi a livello di istruzione, errori e avvisi e eventi broker abilitati.

  • Controllare l'impostazione dell'istanza di SQL Server per le opzioni di connessione predefinite. A tale scopo, aprire SQL Server Management Studio, fare clic con il pulsante destro del mouse su Server e quindi selezionare Proprietà>Connessioni>connessioni Opzioni>di connessione predefinite interruzione arrotondamento numerico.

Risoluzione

Per risolvere questo problema, modificare l'opzione di connessione predefinita impostando SET NUMERIC_ROUNDABORT OFF.