如果你只看数据库,一切都很好。你有交易,如果出现问题,一切都会回滚。很好-我喜欢这个。
但是:我想发送邮件。现在我有麻烦了,因为我无法回滚。
例子:
- 交易开始
- 邮件被发送
- 其他事情完成(在数据库内)
- 出了点问题。
- 回滚。
如何解决这个问题是一个不同的问题,而不是这个。
这个问题一般怎么称呼这个。在这个例子中是关于发送邮件。但是,一旦您在事务边界之外的系统中修改某些内容,就会出现同样的问题。
这个问题有名字吗?
如果您想从目录导入文件,则会出现大致相同的问题。如果您在事务中删除文件,则事务可能会失败并且文件已被删除但从未导入。或者您在交易后删除文件。然后文件的删除可能会失败,并且文件会被第二次导入。
我不想为此重新发明解决方案。这就是为什么我需要这个问题的匹配项。然后我可以阅读一些论文并了解 2018 年的“最新技术”。
Oracle PL/SQL 关键字
AUTONOMOUS_TRANSACTION
将导致过程创建另一个会话、执行事务、仅提交/回滚该私有事务,并将流控制返回给父级。哦..永远不要发送关于未提交数据的电子邮件。
编辑:(由于原始帖子的编辑)
这种类型的问题称为
bug
.解决办法是:
TRANSACTION
COMMIT
。电子邮件示例
你应该有一个
sendEmail
应该在 之后调用的过程commit
。如果要在 之前调用该过程
commit
,则需要向将rollback
与主事务一起使用的队列中添加一行。对于 Oracle,这将是Advance Queuing
或者包APEX_MAIL
通过将它放在一个单独的过程中,您可以
sendEmail
根据 [最终用户] 的请求进行第二次。工艺文件
您有一个包含几个步骤的算法,其中每个步骤都可能失败。这实际上与您的
sendEmail
问题不同。您需要记录您正在处理的内容、您在算法中的位置,以及该步骤是成功还是失败。
为了从任何步骤的错误中恢复,过程的每个步骤都需要定义为离散的
TRANSACTION
。在 Oracle 中,我会有这些程序(每个 1 个程序
TRANSACTION
):这是基于下表:
上的
UNIQUE
约束FILE_NAME
可防止同一文件被处理两次。我认为您正在寻找的术语可能是脏读:
您正在描述分布式事务。请注意,术语“事务”比简单的“数据库事务”具有更普遍的含义。
在分布式事务中,不同的成员可能具有不同的 ACID 属性(例如,不一定保证电子邮件会被传送)、实现这些属性的不同方法以及不同的故障场景。
为了确保分布式事务的一致性,通常使用称为事务协调器(或管理器)的外部实体来控制每个成员(也可以称为资源或资源管理器)的承诺。一种常见的方法是两阶段提交(2PC)。
如果您在 Internet 上搜索“分布式系统中的一致性”,您会发现大量关于该主题的资料。
你描述的是分布式事务的愿望,只是你没有分布式事务管理器,没有回滚的可能性。最简单的方法是使用队列(外部)或 sql server broker 将循环与实际发送分离。参见例如: http: //python-rq.org/
对于从数据库事务调用外部进程的实际组合,我没有特定的术语,但我会将此问题归类为紧密耦合。
根本问题是您将电子邮件的发送与数据库事务紧密耦合。
解决这个问题的方法是将它们松耦合。
从技术上讲,您可以通过多种方式解决这个问题,大致按照从丑到美的顺序:
隐式提交
我相信是您正在寻找的术语。这些是可以/不会遵守的声明
Transactions
甲骨文
MySQL
SQL服务器
数据库-ddls-和-隐式提交
最有趣的是:
sp_send_dbmail (Transact-SQL)
工作流程只是需要注意,
代替
尝试
(捕获结束行计数到变量 B 或文件)
如果 A 和 B 变量匹配,您就知道有错误。
改变工作流程并尝试使用你已经拥有的优势,变量比较等。
这是项目的“需求工程”阶段没有考虑到的问题。不应将其视为数据库系统的问题,因为数据库正在按其应有的方式执行。发送邮件是因为它(还)不是正确业务逻辑的一部分。
它被称为业务逻辑缺陷,甚至可能是业务逻辑问题。
商业逻辑
参考资料:业务逻辑(Wikipedia.org)
业务逻辑缺陷/问题
参考:业务逻辑漏洞和业务逻辑缺陷的一些常见场景(网络安全社区)
参考:危及应用程序安全的常见业务逻辑缺陷(SecurityWeek.com)