【问题标题】:C# TransactionScope with OleDB and OracleC# TransactionScope 与 OleDB 和 Oracle
【发布时间】:2016-02-10 10:28:16
【问题描述】:

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

我想使用 TransactionScope 代替外部 using 部分。请看下面我的测试代码:

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 (Problems with TransactionScope and Oracle) ,但它似乎符合我需要实现的目标。我发现关于如何跨连接池连接桥接单个事务的信息非常少。

编辑 - 2 月 11 日

我从 OleDB 切换到 ODP.Net 并设法得到一个官方的 Oracle ORA 错误...

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

可悲的是,我认为这是 Oracle 错误?我发现论坛帖子表明版本 10.2.0.2 有这个错误,但我在 10.2.0.4 上?

希望有人可以提供帮助!谢谢

【问题讨论】:

    标签: c# oracle transactions oledb connection-pooling


    【解决方案1】:

    要与 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)));

    【讨论】:

    • 能否复制链接中的相关数据?这样,如果将来链接失效,它仍然是一个有用的答案
    • 欢迎提供解决方案链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted.
    【解决方案2】:

    所以,我的回答是:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-20
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多