sql-server - SQL Server 从触发器触发异步更新?

标签 sql-server asynchronous sql-server-2000

如果用户向表中插入行,我希望 SQL Server 执行一些额外的处理 - 但不是在用户事务的上下文中。

例如用户授予对文件夹的读取权限:

UPDATE Folders SET ReadAccess = 1
WHERE FolderID = 7

就用户而言,我希望这是原子操作的结束。实际上,我现在必须找到所有子文件和文件夹并给它们ReadAccess

EXECUTE SynchronizePermissions

这是一个潜在的冗长操作(超过 2 秒)。我希望这个冗长的操作“稍后”发生。它可以在 0 秒后发生,并且在碳单元有机会考虑它之前,异步更新已完成。

如果需要(即触发),我如何异步运行这个必需的操作?

理想的应该是:

CREATE TRIGGER dbo.Folders FOR INSERT, UPDATE, DELETE AS
   EXECUTEASYNCHRONOUS SynchronizePermissions

CREATE TRIGGER dbo.Folders FOR INSERT, UPDATE, DELETE AS
   EXECUTE SynchronizePermissions WITH(ASYNCHRONOUS)

现在这是作为触发器发生的:

CREATE TRIGGER dbo.Folders FOR INSERT, UPDATE, DELETE AS
   EXECUTE SynchronizePermissions

并且用户每次对 Folders 表进行更改时都被迫等待 3 秒。

我考虑过在用户身上创建一个 Scheduled Task,每分钟运行一次,并检查 PermissionsNeedSynchronizing 标志:

CREATE TRIGGER dbo.Folders FOR INSERT, UPDATE, DELETE AS
   UPDATE SystemState SET PermissionsNeedsSynchronizing = 1

计划任务二进制可以检查这个标志,如果标志打开则运行:

DECLARE @FlagValue int
SET @FlagValue = 0;

UPDATE SystemState SET @FlagValue = PermissionsNeedsSynchronizing+1
WHERE PermissionsNeedsSynchronizing = 1

IF @FlagValue = 2
BEGIN
   EXECUTE SynchronizePermissions

   UPDATE SystemState SET PermissionsNeedsSynchronizing = 0
   WHERE PermissionsNeedsSynchronizing = 2
END

计划任务的问题是: - 它可以运行的最快速度是每 60 秒 - 它受到 polling 解决方案的影响 - 它需要一个可执行文件

我更喜欢 SQL Server 可以触发计划任务的方式:

CREATE TRIGGER dbo.Folders FOR INSERT, UPDATE, DELETE AS
   EXECUTE SynchronizePermissionsAsychronous


CREATE PROCEDURE dbo.SynchronizePermissionsAsychronous AS

   EXECUTE sp_ms_StartWindowsScheduledTask @taskName="SynchronousPermissions"

这个问题是: - 没有sp_ms_StartWinodowsScheduledTask系统存储过程

所以我正在寻找更好的解决方案。


更新:前面的例子是一个问题,五年来一直没有好的解决方案。 3 年前的一个没有好的解决方案的问题是我需要在插入/更新后更新元数据列的表。元数据在在线交易处理中计算时间太长,但我可以在 3 或 5 秒后出现:

CREATE TRIGGER dbo.UpdateFundsTransferValues FOR INSERT, UPDATE AS

UPDATE FundsTransfers
SET TotalOrderValue = (SELECT ....[snip]....),
    TotalDropValue = (SELECT ....,[snip]....)
WHERE FundsTransfers.FundsTransferID IN (
    SELECT i.FundsTransferID
    FROM INSERTED i
)

我今天遇到的问题是一种在过渡插入或修改行后异步更新某些元数据的方法:

CREATE TRIGGER dbo.UpdateCDRValue FOR INSERT, UPDATE AS

UPDATE LCDs
SET CDRValue = (SELECT ....[snip]....)
WHERE LCDs.LCDGUID IN (
    SELECT i.LCDGUID
    FROM INSERTED i
)

更新 2:我考虑过创建 native 或托管 dll 并将其用作扩展存储过程。问题在于:

  • 你不能编写二进制文件
  • 我现在可以这样做了

最佳答案

使用队列表,并让不同的后台进程从队列中提取并处理它们。根据定义,触发器本身是用户事务的一部分——这正是他们经常被劝阻的原因(或者至少人们被警告不要在触发器中使用昂贵的技术)。

关于sql-server - SQL Server 从触发器触发异步更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7271922/

相关文章:

sql-server - Excel 错误地将 Date 转换为 Int

c# - 如何在单个事务中将文件写入磁盘并插入数据库记录?

java - 获取ListenableFuture后立即get()

asp.net - ASP.NET WebApi 中的后台异步/等待

sql - 将具有默认值的列添加到 SQL Server 中的现有表

sql server select查询一列相同而另一列不同

c# - 比 if(something) Do It() else Don't() 更好的架构

wcf - 如何应用任务异步模式和 WCF 的 ChannelFactory<TChannel>?

sql-server-2000 - SQL Profiler 2000 不会暂停或停止

c# - SQL 查询的大参数列表