1

我的目标是:

  • 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”上提交会话,什么也不做并抛出异常。我没想到这种行为,所以这让我感到困惑。当我把所有的表格创建放在开始时,一切都开始工作了。在我的测试过程中实际上没有创建任何表,所以我认为这不是问题,但是当我清理代码并将它们移到开始时,一切都自行修复了。

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

4

1 回答 1

0

如果您使用 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
}
于 2012-06-26T11:44:32.607 回答