C# TransactionScope with OleDB and Oracle

本文关键字:and Oracle OleDB with TransactionScope | 更新日期: 2023-09-27 18:33:56

我当前的应用程序将所有数据库操作都放在一个巨大的 Using 语句中,该语句带有连接以确保事务完全提交或回滚,目前如果我有常用方法,它们会传递当前打开的 OleDbConnection 以便可以使用它。

我想使用事务范围代替外部使用部分。 请在下面查看我的测试代码:

private void Test() {        
    string _connectionString = "Provider=OraOLEDB.Oracle.1;Password=XXXXXXXX;Persist Security Info=True;User ID=XXXXXXXX;Data Source=XXXXXXX;min pool size=1;incr pool size=5;decr pool size=2;connection timeout=60;";
    using (TransactionScope _ts = new TransactionScope(TransactionScopeOption.Required))
    {
        using (OleDbConnection _cn = new OleDbConnection(_connectionString))
        {
            _cn.Open(); // Errors Here!
            using (OleDbCommand _cmd = new OleDbCommand())
            {
                _cmd.Connection = _cn;
                _cmd.CommandText = "insert into testtable (TEST) values ('FIRST')";
                _cmd.CommandType = CommandType.Text;
                _cmd.ExecuteNonQuery();
            }
        }
        using (OleDbConnection _cn = new OleDbConnection(_connectionString))
        {
            _cn.Open();
            using (OleDbCommand _cmd = new OleDbCommand())
            {
                _cmd.Connection = _cn;
                _cmd.CommandText = "insert into testtable (TEST) values ('SECOND')";
                _cmd.CommandType = CommandType.Text;
                _cmd.ExecuteNonQuery();
            }
        }
    }
}

我收到的错误是"无法在事务中登记"。 我读过Oracle不喜欢使用TransactionScope(TransactionScope和Oracle的问题(,但它似乎符合我需要实现的目标。 我发现有关如何跨连接池连接桥接单个事务的信息很少。

编辑 - 2月11日

我从 OleDB 切换到 ODP.Net 并设法消除了官方的 Oracle ORA 错误......

ORA-02048: attempt to begin distributed transaction without logging on

可悲的是,从我能找到的我认为这是一个甲骨文错误? 我发现论坛帖子表明 10.2.0.2 版本有此错误,但我使用的是 10.2.0.4?

希望有人能帮忙! 谢谢

C# TransactionScope with OleDB and Oracle

若要与 TransactionScope 一起使用,连接字符串必须包含 "enlist=dynamic">

https://docs.oracle.com/database/121/ODPNT/InstallConfig.htm#r6c1-t14

指定应用程序是否在通过 EnlistTransaction(( 或 EnlistDistributedTransaction(( 调用 OracleConnection.Open 方法后显式登记分布式事务。若要将 ODP.NET 配置为以编程方式启用动态登记,连接字符串必须包含"enlist=dynamic"。

连接字符串,例如: enlist=dynamic;User Id=USER;Password=pass;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=TestDB)));

所以,我的答案是几件事:

首先,我需要在我的客户端上安装 OracleMTS 服务。 其次,我从OleDB(通过Oracle.ManagedDataAccess v12(更改为Oracle.DataAccess v11,它可以工作!

我发现 ODP.Net 客户端的 v12 和 10.2.0.4 有一个错误,即分布式事务失败,但版本 11 有效。 仍然困惑为什么它不适用于 OleDB,但我现在已经解决了它。 希望这可以帮助我这个位置的其他人!