C#回滚发送电子邮件

C#回滚发送电子邮件,c#,asp.net,C#,Asp.net,我在我的网站上写了一个恢复密码的代码。用户输入他的电子邮件地址,我们给他发送一个新密码。此外,我们还将他在DB中的密码更改为最新密码 问题: 若发送邮件的代码失败,我无法在DB中更改他的密码,若更改密码的代码失败,我无法发送邮件 看一看: public bool RecoverPassword(string email) { try { SceLoginMail sceEmail = new SceL

我在我的网站上写了一个恢复密码的代码。用户输入他的电子邮件地址,我们给他发送一个新密码。此外,我们还将他在DB中的密码更改为最新密码

问题: 若发送邮件的代码失败,我无法在DB中更改他的密码,若更改密码的代码失败,我无法发送邮件

看一看:

public bool RecoverPassword(string email)
        {
            try
            {
                SceLoginMail sceEmail = new SceLoginMail(email, "Recuperação de senha", 5);
                ChangeUserPassword(sceEmail.NovaSenha, email);
                sceEmail.SendEmail();
                sceUsers.CommitOrRollBack(true);
                return true;
            }
            catch (Exception ex)
            {
                sceUsers.CommitOrRollBack(false);
                return false;
            }
        }
如果SendEmail方法中出现异常,我尝试在DB中回滚。但是,如果CommitterRollback方法中出现异常,我无法“回滚”SendMail方法。如果是这样,系统将发送邮件,并且不会在DB上更改它


有任何想法吗?

在数据库事务(以及影响新密码有效性的任何其他事项)完成之前,不要发送电子邮件。这样,如果抛出异常,SendEmail()调用将永远不会执行。

在数据库事务(以及影响新密码有效性的任何其他内容)完成之前,不要发送电子邮件。这样,如果它抛出异常,SendEmail()调用将永远不会执行。

如果您分配了新密码,并且由于某种原因它不会被发送,这并不重要。用户不知道自己的密码。电子邮件不会显示,他们会再次请求。因此,提交数据库,并按顺序发送。

如果您分配了新密码,但由于某种原因它没有被发送,这并不重要。用户不知道自己的密码。电子邮件不会显示,他们会再次请求。因此,提交数据库并按顺序发送。

请参见,请求更改密码和请求获取更改密码的电子邮件的操作是两种不同的现象

当用户请求更改密码时,您只需调用该语句以使用新密码更新数据库。更新后,尝试发送邮件

最好有一个邮箱在里面。因此,当电子邮件发送失败时,它将存储在数据库表发件箱中,您应该在阈值时间后定期尝试


这将确保您继续尝试向用户发送该邮件

请参见,请求更改密码和请求获取更改密码的电子邮件的操作是不同的

当用户请求更改密码时,您只需调用该语句以使用新密码更新数据库。更新后,尝试发送邮件

最好有一个邮箱在里面。因此,当电子邮件发送失败时,它将存储在数据库表发件箱中,您应该在阈值时间后定期尝试


这将确保您继续尝试向用户发送该邮件

不要响应“我丢失了密码”请求而重置密码,而是向用户发送一封带有唯一、一次性、有时间限制的重置URL的电子邮件。只有在允许的时间内访问该URL时才重置密码

这有两个好处:

  • 只有成功发送和接收电子邮件时,才会重置密码
  • 如果帐户所属人员以外的其他人执行“我丢失密码”请求(无论是意外还是故意),则合法帐户持有人的密码不会意外失效

  • 与其响应“我丢失了密码”请求而重置密码,不如向用户发送一封带有唯一、一次性、有时间限制的重置URL的电子邮件。只有在允许的时间内访问该URL时才重置密码

    这有两个好处:

  • 只有成功发送和接收电子邮件时,才会重置密码
  • 如果帐户所属人员以外的其他人执行“我丢失密码”请求(无论是意外还是故意),则合法帐户持有人的密码不会意外失效

  • 然后,如果SendMail()方法中发生异常,我确实更改了他的密码,但没有发送邮件。用户将无法访问系统,因为他的密码已更改,他不知道要发送什么。@Oz塞内加尔-为那些边缘案例的客户支持提供电子邮件地址。如果网络中断和其他技术问题是一个真正的问题,那么使用消息队列将电子邮件发送到带外。不过,最后,这里只有这么多技术解决方案可以做:用户可能只是提供了一个无效(或不正确)的地址。@Oz塞内加尔-当然,但您可以捕获并(假定,除非您的邮件服务器着火)从电子邮件恢复/重试。如果您绝对不能接受密码更改或SendMail,除非两者都成功,那么您需要实现更复杂的逻辑来确定何时真正提交DB更改,而不是在异常处理程序中进行简单的回滚。然后,如果SendMail()方法中发生异常,我确实更改了他的密码,并且没有发送邮件。用户将无法访问系统,因为他的密码已更改,他不知道要发送到什么地方。请提供电子邮件地址,以便客户支持这些边缘案例。如果网络中断和其他技术问题是一个真正的问题,那么使用消息队列将电子邮件发送到带外。不过,最后,这里只有这么多技术解决方案可以做:用户可能只是提供了一个无效(或不正确)的地址。@Oz塞内加尔-当然,但您可以捕获并(假定,除非您的邮件服务器着火)从电子邮件恢复/重试。如果您绝对不能接受密码更改或发送电子邮件,除非两者都成功,那么您需要实现更复杂的逻辑来确定何时真正提交数据库更改,而不是在异常处理程序中进行简单的回滚。将这些“新”密码保留在临时密码表中。在用户使用临时密码登录之前,不要替换旧密码。我想这是最好的解决方案[offtopic],这是一个丑陋的API。在我得到什么
    sceUsers.CommitOrRollBack(true)之前,我不得不读了很多遍意思是。哟