【问题标题】:How to have a database trigger code如何拥有数据库触发代码
【发布时间】:2011-01-30 06:10:19
【问题描述】:

我需要一些帮助。

此表中有一个日期列,当该列中的任何日期等于服务器日期时,我需要告诉我的网站/程序发送电子邮件或执行某些通知操作以让用户知道些什么。

我想在服务器上运行一个程序以一定的时间间隔轮询数据库,但问题是如果日期是 11 年 1 月 31 日上午 10:30 并且我的时间间隔是每 5 分钟一次投票不准确,即上午 10:35 的投票。换句话说,当“x”日期恰好在那个日期被击中时,我需要数据库以某种方式通知某些东西。

我希望避免以 1 秒的间隔检查数据库,因为我认为这会对性能造成巨大影响。

我正在使用带有 MSSQL 和 LINQ 实体框架的 ASP.NET MVC 3。

有什么创意吗?

【问题讨论】:

    标签: c# sql-server asp.net-mvc linq


    【解决方案1】:

    您可以使用Quartz.net 来设置这些事件。 Quartz 非常灵活和强大——它是为这类事情设计的。

    【讨论】:

    • 你能说得更具体点吗?我不明白这会如何解决他的问题。
    • 对不起,quartz 是一个作业调度框架。您可以使用 Quartz 注册这些日期/时间并执行相应的任务(向某人发送电子邮件)。 Quartz 基本上是 .NET 的 cron 作业
    • 我要检查一下.. 需要一点时间来实现,但它看起来很像我想做的事情
    【解决方案2】:

    不要让数据库触发代码。让触发器在另一个表中创建一行,其中包含有关刚刚发生的事情的信息。

    有一个单独的程序定期从第二个表读取电子邮件用户或您需要做的任何事情。处理完电子邮件后,让该程序从表中删除该行。

    【讨论】:

    • 这与仅检查带有日期的表格有何不同?拥有触发器不会让我执行实际的 C# 代码
    • @Ryan:您关心的似乎是在正确的时间执行代码。触发器只会在正确的时间在“触发器表”中创建一行。然后,当行出现在“触发器表”中时,C# 代码可以轮询或使用通知来执行。请参阅“Query Notifications in SQL Server (ADO.NET)”。
    • @John - 哦,好的,轮询肯定是不可能的,但我必须查看通知。唯一的问题是它看起来不像我可以将它与 SQL express 一起使用
    • @John - 我很难找到一个像样的地方让我开始。我正在为与数据库相关的东西使用实体框架.. 有什么好的链接吗?
    • @Ryan:你遇到了什么问题? ADO.NET 的东西?
    【解决方案3】:

    我没有任何个人经验,但 Sql Server CLR 集成可能是您正在寻找的答案。从描述看来,您几乎可以编写任何可以针对 .NET 框架进行编译的内容,并将其部署到 sql server 实例,然后 Sql Server 将能够执行它。 http://msdn.microsoft.com/en-us/library/ms254498.aspx

    【讨论】:

      【解决方案4】:

      您要么需要使用调度程序(例如,Oracle 中的 DBMS_SCHEDULER 或 SQL Server Jobs 等),要么找到一些第三方工具,如另一位响应者提到的 Quartz.net。或者也许在投票应用程序中编写如下代码

       select all jobs due in next 5 minutes, order by due date
       while there are jobs
          if the next job is due action it
          else sleep for duration of interval till job due
       loop
      

      【讨论】:

        【解决方案5】:

        这有点脏,但我认为它会为您提供您正在寻找的功能。

        在 Global.asax.cs 中

        public DateTime LastMaxDateTime;
        
        protected void Application_Start(object sender,EventArgs e)
        {
            LastMaxDateTime = GetMaxDateTime();
        
            Thread bgThread=new Thread(BackgroundThread_CheckDatabase);
            bgThread.IsBackground=true;
            bgThread.Start();
        }
        
        private void BackgroundThread_CheckDatabase()
        {
            while(true)
            {
                DateTime dtMaxDateTime = GetMaxDateTime();
                if(dtMaxDateTime > this.LastMaxDateTime)
                {
                    //Send Notifications
                    this.LastMaxDateTime=dtMaxDateTime;
                }
        
                Thread.Sleep(5000); //5 seconds
            }
        }
        
        private DateTime GetMaxDateTime()
        {
             //function that returns DateTime from something like "SELECT MAX(DateTimeColumn) FROM [MyTable]"
        }
        

        基本上,代码会跟踪表中最新的 DateTime,并在每次轮询时检查数据库中自上次检查以来是否有更新的 DateTime。如果是这样,您可以发送通知。如果您不希望表中有许多记录可能导致竞争条件,那么我认为这不是快速解决方案的问题。

        【讨论】:

          【解决方案6】:

          最有效的方法是让应用程序运行事件驱动而不是轮询。

          例如,让一个线程在数据库中查询最早的预定事件并在此之前休眠。然后让另一个线程同步等待表更改(例如,在 PostgreSQL 中,这将是 NOTIFY/LISTEN 语句)并向第一个线程发出信号以检查最早的事件是否已更改。

          【讨论】:

            【解决方案7】:

            最简单的方法是跟踪您上次检查的日期。再次检查时,拉出所有大于上次检查日期且小于或等于新检查日期的行。为确保您执行它们,您可以添加一列以显示执行操作的时间并进行更新。使用该新列上的索引,每秒检查一次是否有 NULL DateExecuted 的行不应该有任何性能问题。

            您还可以提前阅读并按触发日期对即将到来的项目进行排序,然后执行 Thread.Wait() 直到准确地说下一个出现。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-06-06
              • 1970-01-01
              • 2019-09-14
              • 1970-01-01
              • 2018-12-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多