1

我有一个预订酒店的网站。预订成功后,将向客户发送一封电子邮件。我这样做如下:

- Update table "booking"
- Check the result
   + If true, send email
   + Else return error

但是,如果没有发送电子邮件怎么办?已插入数据库但未发送电子邮件。这使得预订操作不正确。如何进行数据库操作和发送电子邮件交易?有什么简单的方法吗?A 和 B 必须成功或都不成功。

4

4 回答 4

6

严格意义上的事务不能在数据库内部和数据库之外扩展某些东西。所以我们必须将“交易”重新定义为,要么所有操作都失败,要么全部成功。

这是一个想法:

  • 启动数据库事务
    • 更新表“预订”
    • 将撤消记录写入表中,状态为“已更新,未发送”。这需要有一些 ID,可用于撤消预订
  • 提交数据库事务
  • 如果失败,退出(无需回滚)

  • 发送电子邮件

  • 如果一切顺利
    • 删除撤消记录
    • 返回“成功”
  • 别的
    • 使用撤消记录撤消预订
    • 删除撤消记录
    • 返回“错误”

有两点需要理解:

  • 在操作系统崩溃、断电等情况下,您必须手动检查撤消表并将其与邮件服务器日志进行比较:崩溃可能发生在邮件刚刚失败或邮件刚刚发送但未记录的情况下
  • 最重要的是:我还没有看到一个快速的机制,它可靠地告诉我们是否已经发送了一封电子邮件。我的意思是真的发送,而不是在某个地方排队
于 2012-07-23T10:42:22.407 回答
4

如果您使用 InnoDB,则可以使用数据库事务:

伪代码:

Start DB transaction
Update table "booking"
Check the result
If true, send email
If email sends, commit your transaction
Else rollback your transaction, and return error

此处有关交易的更多信息:http: //dev.mysql.com/doc/refman/5.0/en/commit.html

于 2012-07-23T10:34:08.747 回答
2

但是,如果没有发送电子邮件怎么办?已插入数据库但未发送电子邮件。这使得预订操作不正确。如何进行数据库操作和发送邮件交易?有什么简单的方法吗?A 和 B 必须成功或都不成功。

好吧,我想说:开始一个事务,将数据输入数据库并测试是否成功。如果成功,请发送电子邮件。如果数据输入和电子邮件发送都成功,则提交事务。如果其中任何一个都不成功,则回滚事务。

那就是说;没有可靠的方法来确定电子邮件是否已成功发送到电子邮件地址。您可以检查接受服务器的 SMTP 状态代码,但这并不能保证您的电子邮件以后不会被退回。

于 2012-07-23T10:37:03.947 回答
0

status_flag DEFAULT 0您可以通过在主表上添加额外的列来实现这一点

脚步:

1. Update table "booking" SET col1 = val1, status_flag = 1 WHERE tr_id = "abc"

2. Send Email

3. Update table "booking" SET status_flag = 2 WHERE tr_id = "abc"

因此,如果您在预订表中找到任何status_flag值为 1 的记录,那么这些记录可能是发送电子邮件失败的记录。

因此,您可以从同一脚本重新发送电子邮件,也可以添加另一个 cron-job 脚本来识别失败的条目并采取相应的措施。

于 2012-07-23T10:40:15.293 回答