使用asp.net和Ms SQL重复发生的事件提醒

时间:2015-01-27 06:31:09

标签: c# asp.net sql-server

我被要求为我编写的某些需要发送提醒电子邮件的软件添加功能。

提醒可能会再次发生;例如,它可能每3天或每2周重复一次。提醒也有开始和结束日期。我创建了一个包含以下字段的SQL表:

event_id
event_name
event_Description
event_startDate
event_endDate
RecurrenceType (e.g. Daily, Weekly, Monthly,Yearly)
Intarval 
event_ActiveFlag

我现在需要编写一个每次运行并发送提醒的存储过程。我通过C#控制台应用程序发送没有问题;我遇到的麻烦是我无法弄清楚如何在当天重现。

1 个答案:

答案 0 :(得分:2)

无论如何,您无法绕过需要执行计算来确定给定事件的重复日期列表。 “计算”我指的是类似下面的伪代码:

foreach(event in activeEvents)
{
    while(recurrenceDate <= currentDate && recurrenceDate <= event.EndDate)
    {
      event.RecurrenceDates.Add(recurrenceDate);
      recurrenceDate.AddDays(event.IntervalLengthInDays);
    }
}

我强烈建议您使用Douglas Day's excellent .NET iCal library请务必阅读许可条款以确保您可以在您的应用中使用此 ,尽管它们非常宽松)来计算重复日期你,因为尽管看起来很简单,但实际上很难正确处理所有角落案件。

这将为您提供事件发生的日期列表,直至当前日期。有两个问题:您何时何地应该执行此计算?

至于哪里,我推荐在C#应用程序中,因为你已经声明你有这样一个组件。绝对有可能在SQL数据库中以高性能,基于集合的方式执行此操作;然而,显而易见,直观的编码方式是使用循环。 C#非常适合循环; SQL不是。当你(或其他人)在六个月后查看它时,以明显的方式执行此操作将使调试和维护变得更加容易。

关于何时,有两种可能性:

选项1:按需:将其作为发送每日提醒爆炸的工作的一部分。

  • 获取所有活动事件的数据
  • 为他们计算重复列表
  • 检查最后一次重复事件(这将是最接近当前日期的事件)以确定该事件是否应作为提醒发送
  • 发送符合条件的提醒

选项2:一次:在创建事件并在系统中输入时执行此操作。

  • 创建事件时,计算截至日期的所有重复日期
  • 将这些日期存储在数据库中的表格中(event_id FK,event_date)
  • 您的提醒作业从预先计算的表中提取符合条件的事件列表(包括活动且具有相应日期)
  • 发送符合条件的提醒

哪个选项更好?我的钱在#1上。为什么呢?

  • 使用选项1,如果我意识到我在我的复发期间意外地输入了“每日”而不是“每周”,更改事件更容易,因为我没有重新计算和重新存储所有重复数据。这是 根据需要计算重复的原因,并且应该胜过除了最严重的性能相关问题之外的所有问题(其中大部分问题都可以通过在问题,或通过更好的负载平衡)。
  • 对于没有定义结束日期的事件,选项2是简并的。这可以通过计算未来的X年来进行管理,但是X年后会发生什么?
  • 每日提醒作业可能会在一夜之间运行,因此不需要超快速执行。这意味着减少执行时间不是优先事项。而且复发计算时间可能无论如何都可以忽略不计;我希望瓶颈是实际的电子邮件发送。但是,如果您要考虑很多活跃的旧事件(“很多”,我的意思是数十亿)和/或您的应用服务器在负载下停止运转,这可能会变得很重要
  • 选项1保存数据库工作。我不是指存储空间(虽然它确实使用较少);除非你有很多(许多万亿)事件,否则这无关紧要。我的意思是它在您的应用服务器和数据库之间来回减少“喋喋不休”,因此连接断开,并发冲突等的可能性更小。请注意这是非常简单的并且确实没有无论哪种方式,除非您的生产环境存在重大问题。