我们正在做一些日志记录问题,我们需要在数据库中写入日志。但是该进程在事务中运行并且通过回滚是我们的新日志也被删除。我可以从事务中写入数据库吗?类似于使用 NO-UNDO 选项在 temptable 中写入...?新的日志仍然保留在数据库中......?
6 回答
另一种可能性是使用应用服务器。应用服务器会话上的事务独立于原始会话中的事务(这就是可选和冗余的“DISTINCT TRANSACTION”语法的全部意义所在)。
另一种选择是使用简单的消息传递系统。一个非常容易设置和使用的选项是 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 是一个基于标准的开源消息传递平台,其部署占用空间非常小。无需支付许可费用,再加上可与任何开发环境一起使用的高性能、可靠消息传递,提供了一种支持随处集成的解决方案
活动MQ
Apache ActiveMQ (tm) (http://activemq.apache.org/) 是最流行和最强大的开源消息传递和集成模式服务器。Apache ActiveMQ 速度快,支持许多跨语言客户端和协议,带有易于使用的企业集成模式和许多高级特性,同时完全支持 JMS 1.1 和 J2EE 1.4。
Apache ActiveMQ 在 Apache 2.0 许可下发布。
兔MQ
RabbitMQ 是一个消息代理。主要思想非常简单:它接受和转发消息。您可以将其视为邮局:当您将邮件发送到邮箱时,您很确定邮递员先生最终会将邮件递送给您的收件人。使用这个比喻 RabbitMQ 是一个邮箱、一个邮局和一个邮递员。
RabbitMQ 和邮局之间的主要区别在于它不处理纸张,而是接受、存储和转发二进制数据块 - 消息。
请随时在 https://bitbucket.org/jmls/stomp问题系统上记录任何问题,并 fork 项目以提交您要添加的所有新功能......
dot.r Stomp 使用宽松的 MIT 许可证 (http://en.wikipedia.org/wiki/MIT_License)
玩得开心,享受!
朱利安
我认为在 ABL 中没有任何方法可以按照您的计划有效地(在整个地方喷洒临时表刷新或其他花絮)或可靠地(如果应用程序因未刷新的临时崩溃而崩溃-表?),正如其他人所提到的。我建议通过使数据库异步写入来减少复杂的日志记录与您的应用程序的耦合,如果可能的话,发生在您的应用程序之外。
由于您使用的是 Windows,因此您可以更改日志记录以使用 .NET log4net库而不是 ABL 构造。log4net 有一些有用的附加程序:
- AdoNetAppender可让您直接登录到数据库
- RemoteSyslogAppender使用 syslog 协议,让您登录到外部 Unix syslog 或rsyslog守护进程(rsyslog 支持将日志消息写入数据库)
- UDPAppender通过 UDP 数据包将日志消息发送到其他要处理的地方(例如,支持写入数据库的logFaces服务器)
如果您必须在 ABL 中执行此操作,那么您可以使用专门为您的日志消息 ( OUTPUT TO STREAM
) 命名的输出流,该输出流写入外部进程正在侦听以处理它的特定位置。该文件可能是由类似的东西创建的管道,mkfifo
或者只是一个常规文本文件,用于监视更改inotify
(不确定这些 Windows 等效项是什么)。这个外部进程将处理解析消息并将它们写入数据库(基本上是重新发明 rsyslog)。
对数据库的每次更改都必须是事务的一部分。如果您没有显式启动一个,它将为您隐式启动,并作用于具有事务功能的下一个外部块。
但是,尽管我不建议您使用子事务。您可以通过在事务范围内显式指定 DO TRANSACTION 来调用子事务。虽然数据库永远不会知道它,但客户端可以回滚子事务,而数据库可以提交事务。
但是为了实现这样的东西,你必须掌握事务范围、块行为和错误处理的概念。
真正的重男轻女。
将您的日志条目写入不可撤消的临时表。当代码将提交事务或事务不活动时(transactionID = ?)让您的代码写出日志条目。
我喜欢 no-undo temp-table 的想法,只要确保将数据库写入部分放在“FINALLY”块中,以防出现未处理的异常。