sp_send_dbmail 阻止并导致 PREEMPTIVE_OS_GETPROCADDRESS

sp_send_dbmail blocks and causes PREEMPTIVE_OS_GETPROCADDRESS

我在存储过程(代码简化)中遇到 msdb.dbo.sp_send_dbmail 的奇怪问题:

SET NOCOUNT ON;
SET XACT_ABORT ON;

-- ...

SET @msg = N'...';
SET @filename = N'...';

EXEC msdb.dbo.sp_send_dbmail
        @recipients = 'mailaddr@example.com'
        , @blind_copy_recipients = 'another_mailaddr@example.com'
        , @from_address = 'senders_mail@example.com'
        , @subject = N'...'
        , @body = @msg
        , @query = N'SET NOCOUNT ON; SELECT <something> FROM <a_view>;'
        , @execute_query_database = N'<same database the proc resides in>'
        , @query_result_width = 8000
        , @attach_query_result_as_file = 1
        , @query_attachment_filename = @filename
        , @query_result_header = 1
        , @query_result_separator = ';'
        , @query_result_no_padding = 1
        , @exclude_query_output = 1;

我有一个数据库用户,它是存储过程的 db_datareaderEXECUTE 权限的成员。此外,分配的服务器登录映射到 msdbDatabaseMailUserRole 的成员。只有 1 个邮件配置文件 public 并标记为 default.

SSMS 一切正常:连接用户凭据并执行存储过程。太棒了!

第一个奇怪之处:如果我以 sysadmin 身份登录并尝试 EXECUTE AS 它不起作用。好吧,我发现一些东西指出这有问题。

但是主要问题是这样的:我从使用 jTDS 驱动程序连接的第 3 方 Java 应用程序调用过程(不知道这是否是重要的)。应用程序执行过程...没有发生任何其他事情(没有日志条目,任务冻结)。

在 activity 监视器中,我看到以下内容:

更糟糕的是,我无法终止此进程。如果我尝试这样做,activity 监视器中的 Command 列仅显示 KILLED/ROLLBACK.

KILL <PROCESS-ID>显示

spid <...>: Transaction rollback in progress. Estimated rollback completion: 0% Estimated time left: 0 seconds.

我必须重新启动整个实例才能摆脱该进程。

这里发生了什么?

终于在这里找到了答案:blocking from xp_sysmail_format_query waittype of preemptive_os_getprocaddress

似乎Java应用程序显式打开了一个事务(连续调用了2次存储过程)。将数据库适配器的自动提交选项设置为 on 后一切正常。