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_datareader
和 EXECUTE
权限的成员。此外,分配的服务器登录映射到 msdb
和 DatabaseMailUserRole
的成员。只有 1 个邮件配置文件 public
并标记为 default
.
SSMS 一切正常:连接用户凭据并执行存储过程。太棒了!
第一个奇怪之处:如果我以 sysadmin
身份登录并尝试 EXECUTE AS
它不起作用。好吧,我发现一些东西指出这有问题。
但是主要问题是这样的:我从使用 jTDS 驱动程序连接的第 3 方 Java 应用程序调用过程(不知道这是否是重要的)。应用程序执行过程...没有发生任何其他事情(没有日志条目,任务冻结)。
在 activity 监视器中,我看到以下内容:
- 进程<...>
- 数据库
master
(??? 我从来没有连接到这个
分贝!)
- 任务状态运行
- 等待类型
PREEMPTIVE_OS_GETPROCADDRESS
- 头部阻滞剂
1
更糟糕的是,我无法终止此进程。如果我尝试这样做,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
后一切正常。
我在存储过程(代码简化)中遇到 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_datareader
和 EXECUTE
权限的成员。此外,分配的服务器登录映射到 msdb
和 DatabaseMailUserRole
的成员。只有 1 个邮件配置文件 public
并标记为 default
.
SSMS 一切正常:连接用户凭据并执行存储过程。太棒了!
第一个奇怪之处:如果我以 sysadmin
身份登录并尝试 EXECUTE AS
它不起作用。好吧,我发现一些东西指出这有问题。
但是主要问题是这样的:我从使用 jTDS 驱动程序连接的第 3 方 Java 应用程序调用过程(不知道这是否是重要的)。应用程序执行过程...没有发生任何其他事情(没有日志条目,任务冻结)。
在 activity 监视器中,我看到以下内容:
- 进程<...>
- 数据库
master
(??? 我从来没有连接到这个 分贝!) - 任务状态运行
- 等待类型
PREEMPTIVE_OS_GETPROCADDRESS
- 头部阻滞剂
1
更糟糕的是,我无法终止此进程。如果我尝试这样做,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
后一切正常。