【发布时间】:2014-03-26 19:09:02
【问题描述】:
我们在数据库中有一个电子邮件队列表。它包含主题、HTML 正文、地址、地址等。
在Global.asax 中,每个间隔都会调用Process() 函数,该函数会发送一定数量的电子邮件。代码如下:
namespace v2.Email.Queue
{
public class Settings
{
// How often process() should be called in seconds
public const int PROCESS_BATCH_EVERY_SECONDS = 1;
// How many emails should be sent in each batch. Consult SES send rates.
public const int EMAILS_PER_BATCH = 20;
}
public class Functions
{
private static Object QueueLock = new Object();
/// <summary>
/// Process the queue
/// </summary>
public static void Process()
{
lock (QueueLock)
{
using (var db = new MainContext())
{
var emails = db.v2EmailQueues.OrderBy(c => c.ID).Take(Settings.EMAILS_PER_BATCH);
foreach (var email in emails)
{
var sent = Amazon.Emailer.SendEmail(email.FromAddress, email.ToAddress, email.Subject,
email.HTML);
if (sent)
db.ExecuteCommand("DELETE FROM v2EmailQueue WHERE ID = " + email.ID);
else
db.ExecuteCommand("UPDATE v2EmailQueue Set FailCount = FailCount + 1 WHERE ID = " + email.ID);
}
}
}
}
问题是它时不时地发送一封电子邮件。
上面的代码有什么理由可以解释这种双重发送吗?
按照 Matthews 的建议进行小测试
const int testRecordID = 8296;
using (var db = new MainContext())
{
context.Response.Write(db.tblLogs.SingleOrDefault(c => c.ID == testRecordID) == null ? "Not Found\n\n" : "Found\n\n");
db.ExecuteCommand("DELETE FROM tblLogs WHERE ID = " + testRecordID);
context.Response.Write(db.tblLogs.SingleOrDefault(c => c.ID == testRecordID) == null ? "Not Found\n\n" : "Found\n\n");
}
using (var db = new MainContext())
{
context.Response.Write(db.tblLogs.SingleOrDefault(c => c.ID == testRecordID) == null ? "Not Found\n\n" : "Found\n\n");
}
有记录时返回:
找到
找到
找不到
如果我在删除 sql 查询后使用这个 method to clear the context cache,它会返回:
找到
找不到
找不到
但是仍然不确定这是否是问题的根本原因。我认为锁定肯定会停止双重发送。
【问题讨论】:
-
我不熟悉 EF 如何缓存数据,但可能是上下文包含 EF 不知道您的原始 SQL 语句可能使缓存无效的缓存数据。此外,当队列中有电子邮件时,您的
Any语句可能是负面优化。 -
我认为问题是你
process()函数需要更多时间然后1sec才能执行。导致第一次发送数据的情况在第二次条件检查中未更新。 -
@avi 这就是锁定的目的
-
@TomGullen:观看
Amazon非常有趣,我也在同一时间工作。除此之外,我能看到QueueLock包含什么吗? -
@Matthew 感谢您的关注,您说得对,负面优化已修正。 QueueLock 只是一个用于锁定静态方法的对象
标签: c# asp.net email locking queue