- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我已经实现了从 Oracle AQ 中取出消息并将其作为 IObservable 公开给系统。工作流程如下:-
我意识到一个潜在的问题,那就是当消息出列时,事务会立即提交,而不是等待它被应用程序成功使用。下面是我正在使用的代码,但需要建议在应用程序成功使用事务后在哪里/如何提交事务。目前,它在私有(private) Dequeue 方法中启动并提交/回滚事务。
public sealed class Queue<T> : IQueue<T> where T : IQueueDataType
{
private readonly OracleConnection _connection;
private readonly string _consumerName;
private readonly IQueueSetting _queueSetting;
private readonly IDbConnectionFactory _dbConnectionFactory;
private OracleAQQueue _queue;
private IObservable<T> _messages;
private bool _isDisposed;
public Queue(IDbConnectionFactory dbConnectionFactory, IDalSettings dalSettings, IQueueSetting queueSetting)
{
_dbConnectionFactory = dbConnectionFactory;
_connection = dbConnectionFactory.Create() as OracleConnection;
_consumerName = dalSettings.Consumer;
_queueSetting = queueSetting;
}
public void Connect()
{
_connection.Open();
_queue = new OracleAQQueue(_queueSetting.QueueName, _connection)
{
DequeueOptions = { Wait = 10, Visibility = OracleAQVisibilityMode.Immediate , ConsumerName = _consumerName, NavigationMode = OracleAQNavigationMode.FirstMessage, DequeueMode = OracleAQDequeueMode.Remove},
UdtTypeName = _queueSetting.QueueDataTypeName,
MessageType = OracleAQMessageType.Udt
};
_queue.NotificationConsumers = new[] { _consumerName };
_messages = Observable
.FromEventPattern<OracleAQMessageAvailableEventHandler, OracleAQMessageAvailableEventArgs>(
h => _queue.MessageAvailable += h, h => _queue.MessageAvailable -= h)
.Where(x => x.EventArgs.AvailableMessages > 0)
.Select(x =>
{
try
{
Log.Info("Msg received", "Queue", _queueSetting.QueueName);
OracleAQMessage msg = Dequeue();
Log.Info("Msg received id " + msg.MessageId, "Queue", _queueSetting.QueueName);
return (T)msg.Payload;
}
catch (Exception e)
{
}
}).Publish().RefCount();
}
private OracleAQMessage Dequeue()
{
using (var connection = _dbConnectionFactory.Create() as OracleConnection)
{
try
{
connection.Open();
using (OracleTransaction transaction = connection.BeginTransaction())
{
try
{
OracleAQMessage msg = _queue.Dequeue();
**transaction.Commit();**
return msg;
}
catch (Exception e)
{
**transaction.Rollback();**
throw;
}
}
}
catch (Exception e)
{
Log.Error(string.Format("Error occurred while connecting to database to dequeue new message. Error : {0}", e),
"Dequeue", GetType().FullName);
throw;
}
finally
{
connection.Close();
}
}
}
public IObservable<T> GetMessages()
{
return _messages;
}
public void Dispose()
{
if (!_isDisposed)
{
if (_queue != null)
{
_queue.Dispose();
}
_connection.Dispose();
_isDisposed = true;
}
}
}
如果不使用 IObservable
,我只公开一个事件提交和回滚事务将非常容易,但我喜欢我可以用 IObservable
做的事情,即我可以运行Linq
但不知道如何提交事务。
最佳答案
我认为这里没有简单的解决方法。如果我理解正确的话:
IObservable
公开事件流,问题是 IObservable
是一种单向机制。一旦你发布了一条消息(在我们的例子中,你从这个 Oracle 队列中得到了一些东西),目的不是跟踪它,而是稍后决定是否提交/回滚。所以你的选择几乎是将你的应用程序逻辑填充到某种形式的处理程序中:
Func<OracleMessage, bool> isMessageCommitable; //...application handling logic here
var appHandledMessages = oracleSourceMessages
.Select(m => Tuple.Create(m, isMessageCommitable(m)))
.Publish()
.RefCount();
appHandledMessages
.Where(t => t.Item2)
.Subscribe(t => Commit(t.Item1));
appHandledMessages
.Where(t => !t.Item2)
.Subscribe(t => Rollback(t.Item1));
...或设置IObservable
s 指向另一个方向,它将从应用程序推回队列,哪些消息应该被提交/回滚。您可能需要两个,一个用于提交,一个用于回滚,这些可能应该传递到 Queue<T>
的构造函数中。 .
祝你好运。
关于c# - 带有 Reactive Extension 和事务 ODP.NET 的 Oracle AQ 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41565039/
我有一个 VS 2012 Web 项目。我安装了 ODP.NET,因为我们是 Oracle Workshop。我继承了一个使用 Oracle.ManagedAccess.Data 和 EF 的项目。
我想念什么? connectionString =“Data Source = TEST_ORACLE;集成安全性=是;”/> [ArgumentException:“集成安全性”是无效的连接字符串属
我必须从 .NET 代码连接 Oracle 11g DB。为此,我在阅读了一些论坛帖子后安装了 ODP.NET,我意识到我也需要安装 Oracle 客户端。 这是真的吗?我看到 Oracle 客户端的
当我尝试使用 ODP.NET 执行创建过程时,我得到了 ORA-24344: success with compiling error 的信息。但是,当我在 SQL Developer 中运行相同的语
最初我使用 oraoledb.oracle 提供程序来连接到 Oracle 数据库,并且很容易构建连接字符串: Provider=OraOLEDB.Oracle;User Id=myId;Passwo
在一个站点上,我可以使用SQL Developer连接到Oracle数据库,将其长时间闲置(例如,> 60分钟),然后返回,就可以了。在第二个站点上,如果它闲置超过5-10分钟(我还没有确切计算),它
我有一个托管在 IIS 7 上的 Web 应用程序,使用 Oracle.DataAcess.dll for .NET 来执行对 Oracle 数据库的连接和查询。 上周突然遇到这个组件抛出的无数错误,
我正在尝试填充数据表,但数据适配器返回异常:OverflowExeption(除以零)。这是我的命令文本: select value1/value2 from table value1和value2在
托管和非托管 Oracle ODP.Net 驱动程序之间是否存在任何性能基准? (即,除了架构/部署简单性之外,迁移到托管驱动程序是否有任何优势) 最佳答案 我想分享一些结果。我认为与部署的简便性相比
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 8 年前。 Improve
我正在使用 ODP.NET 托管驱动程序 12.1.0.2.1(ODAC 12c 第 3 版)并发现了严重错误。如果在命令执行期间超时导致连接池中的线程和连接丢失。 这个测试总是失败: [TestMe
我在尝试为应用程序生成跟踪文件时遇到问题。 正在尝试解决 Oracle 问题,但未写入跟踪文件。这是我的 app.config,它作为 exename.app.config 被移动到 Release
我正在尝试将基于 ODP.NET 11g 构建的现有应用程序升级到 ODP.NET 12c,希望它能提高数据库调用和数据检索的性能。在这方面,我安装了最新的 ODP.NET 12c 并将所有 Orac
干草,我的系统需要使用相同的连接(异步)执行几个主要的 SQL(在 Oracle 数据库上)。 这个问题的最佳做法是什么?1.打开单连接并在不同线程上执行每个SQL语句(线程安全吗?)2. 为每个SQ
我尝试搜索,但没有找到我的问题的明确答案。我正在从 SQL Server 切换到 Oracle,但前端仍然使用 C#。我正在使用 ODP.Net。我在 Oracle 中有一个这样的存储过程: Crea
我最近开始在使用 ODP.NET (Oracle.DataAccess 4.112.3) 的 C# (4.0) 应用程序上进行测试 我将此项目设置为面向任何平台并发布应用。 当我在客户端机器上运行程序
我还没有在任何地方找到明确说明这一点,但我在网上找到的一堆例子都符合我一直在做的事情。 我有一个 C# 类,它使用 ODP.net 连接到 Oracle 数据库并运行程序包中的过程。 我的包有存储过程
我正在尝试使用 ODP.NET 版本 2.111.6.20 为我的 .NET 应用程序配置连接池。数据库是 Oracle 11.1。 我在 .NET 2.0 应用程序中使用以下连接字符串: 数据源=p
在我之前的 question 中描述的应用程序本身.在 DAL 方面,我使用 Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral,
首先我想说我对 Oracle 数据库一点都不熟悉,所以我的措辞可能不正确,我对某些概念的理解可能是错误的......无论如何,我正在尝试使用 ODP.NET 连接到 Oracle 11g 数据库,每次
我是一名优秀的程序员,十分优秀!