AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 205831
Accepted
guettli
guettli
Asked: 2018-05-05 04:29:41 +0800 CST2018-05-05 04:29:41 +0800 CST 2018-05-05 04:29:41 +0800 CST

非事务保存操作的术语

  • 772

如果你只看数据库,一切都很好。你有交易,如果出现问题,一切都会回滚。很好-我喜欢这个。

但是:我想发送邮件。现在我有麻烦了,因为我无法回滚。

例子:

  1. 交易开始
  2. 邮件被发送
  3. 其他事情完成(在数据库内)
  4. 出了点问题。
  5. 回滚。

如何解决这个问题是一个不同的问题,而不是这个。

这个问题一般怎么称呼这个。在这个例子中是关于发送邮件。但是,一旦您在事务边界之外的系统中修改某些内容,就会出现同样的问题。

这个问题有名字吗?

如果您想从目录导入文件,则会出现大致相同的问题。如果您在事务中删除文件,则事务可能会失败并且文件已被删除但从未导入。或者您在交易后删除文件。然后文件的删除可能会失败,并且文件会被第二次导入。

我不想为此重新发明解决方案。这就是为什么我需要这个问题的匹配项。然后我可以阅读一些论文并了解 2018 年的“最新技术”。

terminology
  • 7 7 个回答
  • 157 Views

7 个回答

  • Voted
  1. Michael Kutz
    2018-05-05T04:46:08+08:002018-05-05T04:46:08+08:00

    Oracle PL/SQL 关键字AUTONOMOUS_TRANSACTION将导致过程创建另一个会话、执行事务、仅提交/回滚该私有事务,并将流控制返回给父级。

    哦..永远不要发送关于未提交数据的电子邮件。

    编辑:(由于原始帖子的编辑)

    如果您想从目录导入文件,则会出现大致相同的问题。如果您在事务中删除文件,则事务可能会失败并且文件已被删除但从未导入。或者您在交易后删除文件。然后文件的删除可能会失败,并且文件会被第二次导入。

    这种类型的问题称为bug.

    解决办法是:

    • 将每个步骤定义为自己的TRANSACTION
      • 您将希望以一种可以根据需要重新运行(或跳过)步骤的方式创建它们
    • 按适当的顺序运行每个步骤。
      • 之前不要发送电子邮件COMMIT。
      • 在成功加载数据之前不要删除文件
    • 您需要跟踪“您所在的位置”以及该步骤是否通过/失败。

    电子邮件示例

    你应该有一个sendEmail应该在 之后调用的过程commit。

    如果要在 之前调用该过程commit,则需要向将rollback与主事务一起使用的队列中添加一行。对于 Oracle,这将是Advance Queuing或者包APEX_MAIL

    通过将它放在一个单独的过程中,您可以sendEmail根据 [最终用户] 的请求进行第二次。

    工艺文件

    您有一个包含几个步骤的算法,其中每个步骤都可能失败。这实际上与您的sendEmail问题不同。

    您需要记录您正在处理的内容、您在算法中的位置,以及该步骤是成功还是失败。

    为了从任何步骤的错误中恢复,过程的每个步骤都需要定义为离散的TRANSACTION。

    在 Oracle 中,我会有这些程序(每个 1 个程序TRANSACTION):

    create or replace
    package file_processing_package
    as
      procedure update_file_processing_status(
                                    p_id       IN files_to_process.id%TYPE
                                  , p_status   IN process_states.id%TYPE);
    
    
      function add_a_file_to_be_processed( p_filename IN files_to_process.file_name%TYPE )
                                   return files_to_process.id%TYPE;
    
      procedure load_data_from_file( p_id in files_to_process.id%TYPE );
    
      procedure process_already_loaded_data( p_id in files_to_process.id%TYPE );
    
      procedure delete_file_from_os( p_id in files_to_process.id%TYPE );
    end;
    /
    

    这是基于下表:

    CREATE TABLE PROCESS_STATES (
      id   int generate by default on null as identity, -- 12c+
      state_desc  varchar2(25) not null,
      constraint process_states_pk primary key (id),
      constraint process_states_uq1 unique (state_desc)
    );
    
    insert into process_states( state_desc ) values ( 'file to be processed' );
    insert into process_states( state_desc ) values ( 'file loaded' );
    insert into process_states( state_desc ) values ( 'processing' );
    insert into process_states( state_desc ) values ( 'processing failed' );
    insert into process_states( state_desc ) values ( 'processing succeeded' );
    insert into process_states( state_desc ) values ( 'delete failed' );
    insert into process_states( state_desc ) values ( 'OK' ); -- delete succeeded
    commit;
    
    CREATE TABLE FILES_TO_PROCESS (
      id               int generate by default on null as identity, -- 12c+
      file_name        varchar2(50) not null,
      process_state_id int not null,
      constraint file_to_process_pk  primary key (id),
      constraint file_to_process_uq1 unique (file_name),
      constraint file_to_process_fk1 foreign key (process_state_id)
                                references (process_states.id)
    );
    

    上的UNIQUE约束FILE_NAME可防止同一文件被处理两次。

    • 6
  2. dbdemon
    2018-05-08T00:48:04+08:002018-05-08T00:48:04+08:00

    我认为您正在寻找的术语可能是脏读:

    当允许事务从已被另一个正在运行的事务修改但尚未提交的行中读取数据时,就会发生脏读(也称为未提交的依赖项)。[...]

    在我们的示例中,事务 2 更改了一行,但没有提交更改。事务 1 然后读取未提交的数据。现在如果事务 2 回滚它的更改(已被事务 1 读取)或更新数据库的不同更改,那么事务 1 的记录中的数据视图可能是错误的。

    • 3
  3. Best Answer
    mustaccio
    2018-05-11T09:31:29+08:002018-05-11T09:31:29+08:00

    您正在描述分布式事务。请注意,术语“事务”比简单的“数据库事务”具有更普遍的含义。

    在分布式事务中,不同的成员可能具有不同的 ACID 属性(例如,不一定保证电子邮件会被传送)、实现这些属性的不同方法以及不同的故障场景。

    为了确保分布式事务的一致性,通常使用称为事务协调器(或管理器)的外部实体来控制每个成员(也可以称为资源或资源管理器)的承诺。一种常见的方法是两阶段提交(2PC)。

    如果您在 Internet 上搜索“分布式系统中的一致性”,您会发现大量关于该主题的资料。

    • 1
  4. detzu
    2018-05-12T20:57:54+08:002018-05-12T20:57:54+08:00

    你描述的是分布式事务的愿望,只是你没有分布式事务管理器,没有回滚的可能性。最简单的方法是使用队列(外部)或 sql server broker 将循环与实际发送分离。参见例如: http: //python-rq.org/

    • 1
  5. Colin 't Hart
    2018-05-13T05:12:31+08:002018-05-13T05:12:31+08:00

    对于从数据库事务调用外部进程的实际组合,我没有特定的术语,但我会将此问题归类为紧密耦合。

    根本问题是您将电子邮件的发送与数据库事务紧密耦合。

    解决这个问题的方法是将它们松耦合。

    从技术上讲,您可以通过多种方式解决这个问题,大致按照从丑到美的顺序:

    • 表中行上的标志,指示是否已发送电子邮件。外部进程可以轮询标志并发送电子邮件。
    • 生成电子邮件并将其存储在表中。然后这些将在同一个事务中提交。外部进程读取和发送需要发送的电子邮件。监视表可以通过轮询或侦听/通知结构(见下)来完成。
    • 使用 listen/notify 构造(Postgres 实现)。数据库事务调用 NOTIFY。当事务提交时,连续运行的侦听进程会收到通知,从而提供所需的隔离和松耦合。
    • 1
  6. JayRizzo
    2018-05-14T22:22:36+08:002018-05-14T22:22:36+08:00

    隐式提交

    我相信是您正在寻找的术语。这些是可以/不会遵守的声明Transactions

    甲骨文

    MySQL

    SQL服务器

    数据库-ddls-和-隐式提交

    最有趣的是:

    sp_send_dbmail (Transact-SQL)

    在没有事务上下文的情况下执行 sp_send_dbmail 时,数据库邮件启动并提交隐式事务。从现有事务中执行 sp_send_dbmail 时,数据库邮件依赖于用户提交或回滚任何更改。它不会启动内部事务。

    工作流程只是需要注意,

    代替

    • 交易开始
    • 邮件已发送
      • 其他事情完成(在数据库内)
        • 出了点问题
    • 回滚。

    尝试

    • 发送邮件“Starting with Snapshot Stats”(捕获起始行计数到变量 A 或文件)
    • 交易开始
      • 其他事情完成(在数据库内)
        • 出了点问题。
    • 回滚。
    • 发送邮件“以快照统计结束”

    (捕获结束行计数到变量 B 或文件)

    如果 A 和 B 变量匹配,您就知道有错误。

    改变工作流程并尝试使用你已经拥有的优势,变量比较等。

    • 0
  7. John K. N.
    2018-05-08T05:49:29+08:002018-05-08T05:49:29+08:00

    这是项目的“需求工程”阶段没有考虑到的问题。不应将其视为数据库系统的问题,因为数据库正在按其应有的方式执行。发送邮件是因为它(还)不是正确业务逻辑的一部分。

    它被称为业务逻辑缺陷,甚至可能是业务逻辑问题。

    商业逻辑

    在计算机软件中,业务逻辑或域逻辑是程序的一部分,它对现实世界的业务规则进行编码,这些规则决定了如何创建、存储和更改数据。它与软件的其余部分形成对比,这些软件可能涉及管理数据库或显示用户界面、系统基础结构或一般连接程序各个部分的较低级别细节。

    参考资料:业务逻辑(Wikipedia.org)

    业务逻辑缺陷/问题

    Web 应用程序已成为 Internet 上业务流程的核心机制。随着越来越多的企业转向互联网模式,导致了各种信息安全问题和漏洞。SQL 注入、跨站点脚本、远程代码执行等等。然而,除了常规漏洞之外,还有许多形式的业务逻辑漏洞通常被攻击者利用。这些漏洞在 QA 期间通常会被忽略,因为该过程旨在测试一段代码应该做什么,而不是可以做什么。业务逻辑缺陷的另一个问题是扫描器无法识别它们,IDS 无法检测到它们,Web 应用程序防火墙无法防御它们。

    因此,业务逻辑漏洞是以对组织造成负面后果的方式使用应用程序的合法处理流程的方式。例如,客户采购订单、银行查询、电汇或在线拍卖等业务流程的自动化要求实体能够访问极其敏感的信息。这些实施不当会导致业务逻辑缺陷。

    参考:业务逻辑漏洞和业务逻辑缺陷的一些常见场景(网络安全社区)

    “业务逻辑是应用程序的预期行为,”NT OBJECTives 的联合首席执行官兼首席技术官 Dan Kuykendall 解释道。“它是控制应用程序核心功能的功能,例如,允许哪些用户看到什么,为各种项目向多少用户收费等。业务逻辑攻击是你可以利用逻辑和作弊的事情应用程序……(它们)很难测试,因为它们需要了解应用程序和安全性。在许多情况下,QA 团队知道业务逻辑,但他们不是安全专家,也没有接受过相关培训巧妙的攻击技巧。”

    参考:危及应用程序安全的常见业务逻辑缺陷(SecurityWeek.com)

    • -1

相关问题

  • 根据数据库完整性的数据有效性和准确性

  • 在 SQL 中,它是复合键还是复合键?

  • 什么是残差谓词?

  • “‘连接’表”是否与弱实体相同?

  • 软件工程师和 DBA [关闭]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve