通过插入触发器安全地发送数据库邮件

Chi*_*isu 2 trigger sql-server-2005 security database-mail

到目前为止,我已经花了大约 30 个小时努力sp_send_dbmail去上班。我终于得到了一些工作,但我严重怀疑它的安全性。我想知道一种更好但快速且易于设置的方法(此时我的时间受到严重限制),以及“理想”(最佳实践)解决方案。

当前 SQL Server 2005 配置

- `After Insert` Trigger on table executes `sp_send_dbmail`
- Database Mail SMTP Account setup (with successful mail test)
- Database Mail Profile setup (with "Public Profile" ticked)
- "guest" account added to "DatabaseMailUserRole"
Run Code Online (Sandbox Code Playgroud)

我发现这篇文章提出了“正确”的解决方案,我阅读了这篇文章,在那里我发现这是一个非常复杂的解决方案,似乎有太多可能出错的事情,更不用说难以维护了。

我对替代解决方案的想法是这些。

1. Setup an Application Role in msdb (this would be my first time using one
    and not even sure if it IS a solution :P), and use it to ensure that email
    can ONLY be generated from the app and not by connecting directly to the server.
2. Abandon the trigger and instead run a job on the table to send email. Definitely
    NOT ideal as I would prefer the email to go out instantly, but at least this
    way I would be able to control the user context. Additionally this is similar
    to the current mechanism, except it would use a Stored Procedure instead of a
    DTS package.
Run Code Online (Sandbox Code Playgroud)

我在这 30 小时内一直在解决的问题以及我询问的原因与执行触发器的安全上下文有关。当我进行测试时,一切都很好,因为我是 DBA,但是当我的用户使用负责生成电子邮件的应用程序时,它会中断,因为他们的凭据不够高,触发器无法执行sp_send_dbmailproc,因此它打破了应用程序。(不幸的是,我的错误处理作为 SQL Server 级别目前不太理想)。

Cad*_*oux 5

您最好简单地插入触发器中的邮件队列表,并让单独的电子邮件进程处理邮件 - 在 SQL Server 代理或外部程序中。

这为您提供了根据需要使用触发器的好处,相对较低的延迟,因为其他作业一旦提交就可以看到邮件,独立管理邮件负载的可扩展性等。

您可以将邮件队列正确包装到事务中。如果邮件服务器暂时不可用或者您有电子邮件地址问题,那么排队应用程序是可靠的。如果需要重新发送邮件,只需重置已发送标志即可。您可以为邮件设置过期时间,这样无法发送到 SMTP 的邮件在一定时间后不会被重试。您可以快速将所有邮件路由到测试邮箱。您可以根据队列中的数据使用附件和其他内容做一些非常有趣的事情,而无需长时间绑定触发器——例如生成报告等。

因此,应用程序将邮件责任卸载到另一个组件,可以自由地完成数据库事务并将成功返回给用户,同时邮件子系统继续其工作,确保您对邮件执行的所有操作都完成。

  • @Chiramisu 需要有多“立即”?鉴于它从 SMTP 服务器跳到 SMTP 服务器时总是存在延迟,在此过程中会检查垃圾邮件(可能多次),并且考虑到大多数普通人不会在电子邮件到达的微秒内阅读他们的电子邮件,时间是一分钟后来真的太慢了​​吗?30 秒后是不是太慢了?这封电子邮件的内容是什么,必须如此即时,如果电子邮件在 10 秒或 40 秒内到达那里,真的会对业务产生影响吗? (4认同)
  • @Chiramisu 对于队列实现,我会推荐 OUTPUT (http://msdn.microsoft.com/en-us/library/ms177564.aspx) 我不能在这篇文章中添加任何内容:http://rusanu.com/2010/03 /26/使用表作为队列/ (2认同)