【问题标题】:Multiple connections, session state多个连接,会话状态
【发布时间】:2012-06-26 11:02:43
【问题描述】:

我的目标是:

  • 1 个持久的数据库连接和事务,用于插入/更新数据,并且可以在所有工作完成后提交或回滚

  • “随意”打开不相关的连接,这些连接不与持久连接共享会话状态 - 这意味着它们“看到”旧数据。这些连接只需要读,不需要写。

我尝试打开一个全新的连接,但它看到了持久连接所做的更改。这有可能实现吗?

注意:我对所有连接使用相同的 Oracle 用户名/密码。

注意 2:Toad(Oracle DB 软件)在提交之前不会“看到”持久连接所做的更改。如果它们被回滚,它们不会出现在数据库中,当它们被提交时,它们会出现。这部分工作正常,只是从我的应用程序打开的其他连接在提交之前会看到它们。

这是我的连接的代码,它看到了它不应该看到的变化:

using (OracleConnection readConnection = new 
       OracleConnection(Settings.OracleConnectionString))
{
    readConnection.Open();

    using (OracleCommand command = new OracleCommand(lastOracleRowQuery, 
                                                     readConnection))
    {
        using (OracleDataReader reader = command.ExecuteReader())
        {
            if (reader.Read())
            {
                for (int i = 0; i < reader.FieldCount; i++)
                    compareValues.Add(reader.IsDBNull(i) ? 
                        null : 
                        reader.GetValue(i));
            }
        }
    }
}

当有另一个 OracleConnection 打开并且有一个事务使用该连接时会发生这种情况。但是,readConnection 不应该是完全不相关的吗?

此读取的结果给出了在 Toad 中同时使用相同查询时不会出现的结果。

已解决

显然,即使创建表失败,Oracle 也会在“CREATE TABLE”上提交会话,不执行任何操作并引发异常。我没想到这种行为,所以这让我感到困惑。当我把所有的表格创建放在开始时,一切都开始工作了。在我的测试过程中实际上没有创建任何表,所以我认为这不是问题,但是当我清理代码并将它们移到开始时,一切都自行修复了。

不过,我仍然不明白 Toad 发生了什么。我可能弄错了什么。或者还有更多我不知道的错误。 :D

【问题讨论】:

  • 如果使用默认的已提交读取,是否有可能您对两者都使用相同的连接/会话? (汇集)。
  • 连接是完全独立的对象,除了两件事:两者都使用相同的用户名/密码,并且创建“读取”连接的函数被调用与持久连接的“使用”块和交易。
  • 我将您建议的 ALTER SESSION 命令添加到读取连接并开始工作。然后,我将其注释掉,它仍然有效。现在我很困惑。
  • 其实alter session并不重要,我想通了。
  • 在 ODP.NET 中默认启用连接池。您可能需要考虑将您想要“隐藏”的 DML 代码包装在 db 中的 pragma 自治过程中。

标签: c# .net oracle


【解决方案1】:

如果您使用 System.Transaction.TransactionScope,则在该范围内创建的所有连接都将被视为单个事务,因此您的持久连接创建的数据将对读取连接可见。

您应该在当前范围内创建一个新的 TransactionScope,范围选项为 TransactionScopeOption.Suppress,在该范围内创建读取连接并在该新范围内执行您的读取操作。您的代码将如下所示。

//Outer Transaction        
using (TransactionScope t = new TransactionScope())
{
        //Create persistence connection and command
        // Execute persistence commands
        //Inner scope to suppress the outer transaction
    using (TransactionScope t1 = new TransactionScope(TransactionScopeOption.Suppress))
    {
        //create read connection
        // Execute read operation
    }
    //continue with write operation
}

【讨论】:

  • 这可以解释我的问题,但我不是,我使用的是 OracleTransaction transaction = connection.BeginTransaction(),然后是 command.Transaction = transaction;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
  • 2011-09-19
  • 2011-01-06
  • 2020-01-09
相关资源
最近更新 更多