繁体   English   中英

电子邮件已发送两次

[英]Emails being sent twice

我们在数据库中有一个电子邮件队列表。 它包含主题,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查询后使用此方法清除上下文缓存 ,它将返回:

发现

未找到

未找到

但是,仍然不确定这是否是问题的根本原因。 我认为锁定肯定会停止两次发送。

您遇到的问题是由于实体框架执行其内部缓存的方式引起的。

为了提高性能,实体框架将缓存实体,以避免数据库命中。

DbSet上执行某些操作时,实体框架将更新其缓存。

实体框架不理解您的"DELETE FROM ... WHERE ..."语句应该使缓存无效,因为EF不是SQL引擎(并且不知道您编写的语句的含义)。 因此,要允许EF发挥作用,您应该使用EF可以理解的DbSet方法。

for (var email in db.v2EmailQueues.OrderBy(c => c.ID).Take(Settings.EMAILS_PER_BATCH))
{
    // whatever your amazon code was...

    if (sent)
    {
        db.v2EmailQueues.Remove(email);
    }
    else
    {
        email.FailCount++;
    }
}

// this will update the database, and its internal cache.
db.SaveChanges(); 

附带说明,您应该尽可能地利用ORM,不仅可以节省调试时间,还可以使代码更易于理解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM