【问题标题】:is it possible to write record as NO-UNDO in transaction?是否可以在事务中将记录写为 NO-UNDO?
【发布时间】:2012-08-15 09:22:34
【问题描述】:

我们正在处理一些日志问题,我们需要在数据库中写入日志。但是该进程在事务中运行并且通过回滚是我们的新日志也被删除。我可以从事务中写入数据库吗?像用 NO-UNDO 选项写在 temptable 中的东西......?新的日志仍然保留在数据库中...?

【问题讨论】:

  • Windows 还是 Unix?您需要将这些日志条目写入的表的结构如何(多少列)?

标签: progress-4gl openedge 4gl


【解决方案1】:

另一种可能性是使用应用服务器。应用服务器会话上的事务独立于原始会话中的事务(这就是可选且冗余的“DISTINCT TRANSACTION”语法的全部意义所在)。

【讨论】:

  • 它并不总是与应用服务器一起运行。没有它,应用程序也必须运行。但是谢谢你的回答。
【解决方案2】:

另一种选择是使用简单的消息传递系统。一个非常容易设置和使用的选项是 STOMP。它是平台中立的,非常容易上手。

Julian Lyndon-Smith 大约一个月前在 PEG 上发布了以下内容,它确实像他说的那样易于设置和使用(我已经尝试过了,我使用了 ApacheMQ,它也非常易于设置和使用) :

在波士顿和芬兰的演讲之后,dot.r 是 很高兴地宣布开源 Stomp 项目,可用 马上。

http://www.dotr.com 或下载 https://bitbucket.org/jmls/stomp , dot.r stomp 程序让你 将您的进度会话连接到任何其他应用程序或服务 连接到同一个消息代理。

支持 Stomp 的开源免费消息代理是:

保险丝

(http://fusesource.com/products/fuse-mq-enterprise/) [现在归红帽公司所有的 Progress 公司] Fuse MQ Enterprise 是一个基于标准的开源消息传递平台,其部署占用空间非常小。缺乏执照 费用与高性能、可靠的消息传递相结合,可以 与任何开发环境一起使用提供了一种解决方案 支持无处不在的集成

ActiveMQ

Apache ActiveMQ (tm) (http://activemq.apache.org/) 是最流行的 和强大的开源消息传递和集成模式服务器。阿帕奇 ActiveMQ 速度快,支持多种跨语言客户端和协议,自带 具有易于使用的企业集成模式和许多高级功能 同时完全支持 JMS 1.1 和 J2EE 1.4。

Apache ActiveMQ 在 Apache 2.0 许可下发布。

RabbitMQ

RabbitMQ 是一个消息代理。主要的想法很简单:它 接受和转发消息。你可以把它想象成一个帖子 办公室:当你向邮箱发送邮件时,你很确定先生。 邮递员最终会将邮件递送给您的收件人。使用这个 比喻 RabbitMQ 是一个邮箱、一个邮局和一个邮递员。

RabbitMQ 和邮局的主要区别在于: 它不处理纸张,而是接受、存储和 转发二进制数据块 - 消息。


请随时在 https://bitbucket.org/jmls/stomp 发布系统,并 fork 项目 为了提交您要添加的所有新功能 ...

dot.r Stomp 使用宽松的 MIT 许可证 (http://en.wikipedia.org/wiki/MIT_License)

玩得开心,享受!

朱利安

【讨论】:

    【解决方案3】:

    对数据库的每次更改都必须是事务的一部分。如果您没有显式启动一个,它将为您隐式启动并作用于具有事务功能的下一个外部块。

    但是,尽管我不建议您这样做,但还是使用子事务。您可以通过在事务范围内显式指定 DO TRANSACTION 来调用子事务。虽然数据库永远不会知道,但是客户端可以回滚子事务,而数据库可以提交事务。

    但是为了实现这样的事情,你必须掌握事务范围、块行为和错误处理的概念。

    RealHeavyDude。

    【讨论】:

    • 我们正在处理子事务和 DO TRANSACTION 块。我已经阅读了有关事务的文档(ABL Essentials - 管理事务),但我没有看到任何关于运行事务异常的信息......很有可能是不可能的 :(...
    • 子交易不是 ABL 中广泛使用的概念。通常它是偶然发生的,如果编译器检测到它(在同一代码块内),它甚至会发出警告,尽管它会编译它。需要明确的是:数据库只知道最外面的事务 - THE TRANSACTION,它完全不知道子事务。然而,已经活动的事务中的每个 DO TRANSACTION 语句都会导致由客户端会话处理的子事务。它可以由客户端撤消,但是当外部事务回滚时 - 所有子事务也是如此。
    【解决方案4】:

    将您的日志条目写入不可撤消的临时表。 当代码将提交事务或事务未处于活动状态(transactionID = ?)时,让您的代码写出日志条目。

    【讨论】:

    • 我正在 NO-UNDO temptable 中写入日志条目。它会在某个时候从这个 temptable 复制到另一个 temptable。但问题是,当我等待事务结束时,系统会崩溃并且没有机会写入数据库。
    • 是的,尽管如果您的系统不稳定,我会更担心崩溃而不是丢失一些日志条目。解决这个问题的唯一方法是写入外部文件,或发布到外部服务(ala STOMP)。如果您写入文件,每个用户/会话都需要写入自己的文件以避免数据冲突。
    • 我们有各种输出管道。其中之一是数据库表。
    【解决方案5】:

    我认为在 ABL 中没有任何方法可以按照您的计划有效地执行此操作(在整个地方喷洒临时表刷新或其他花絮很恶心)或可靠地(如果应用程序因 un-刷新临时表?),正如其他人所提到的。我建议通过使数据库异步写入(尽可能在应用程序外部发生)来减少复杂的日志记录与应用程序的耦合。

    由于您使用的是 Windows,因此您可以更改日志记录以使用 .NET log4net 库而不是 ABL 构造。 log4net 有几个appenders 很有用:

    如果您必须在 ABL 中执行此操作,那么您可以使用专门为您的日志消息 (OUTPUT TO STREAM) 命名的输出流,该输出流写入外部进程正在侦听以处理它的特定位置。该文件可能是由mkfifo 之类的东西创建的管道,或者只是一个常规文本文件,它使用inotify 监视更改(不确定这些在Windows 中的等价物是什么)。这个外部进程将处理解析消息并将它们写入数据库(基本上是重新发明 rsyslog)。

    【讨论】:

    • 我们正在使用progress 10.2B,它在应用服务器上不支持.NET。谢谢你的回答。未来是个好主意:)
    • 当然。我仍然认为 ABL 中最好的方法是使用某种形式的 IPC 与外部进程进行通信。也许创建一个日志类作为外观来隐藏所有复杂性,这也可以让您在初始化时将日志记录到尽可能多的地方。 0MQ 将是在这里用于 IPC 通信的完美之选,但从我的实验来看,不久前 AVM 会阻塞它。我想你可以使用 ActiveMQ/Stomp,但我认为这会带来太多开销,除非你正在实现一个完整的集中式日志服务器。我只是为您的场景使用命名管道。
    【解决方案6】:

    我喜欢 no-undo temp-table 的想法,只要确保将数据库写入部分放在“FINALLY”块中,以防出现未处理的异常。

    【讨论】:

    • 当应用程序被击落时,finally 是否已经白白阻塞了。它必须通过从进程中运行来写入消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 2019-07-25
    • 2023-01-24
    • 2013-12-20
    • 2021-09-15
    • 2018-08-30
    • 1970-01-01
    相关资源
    最近更新 更多