oracle – 随机获取ORA-08177只有一个活动会话

前端之家收集整理的这篇文章主要介绍了oracle – 随机获取ORA-08177只有一个活动会话前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在运行一个创建一个表然后插入一些数据的程序。
这是访问数据库的唯一程序。
随机得到ORA-08177。
实际代码有点复杂,但是我已经编写了一个简单的程序来重现这种行为。
using System;
using System.Data;
using Oracle.DataAccess.Client;

namespace orabug
{
  class Program
  {
    private const string ConnectionString = ""; // Valid connection string here

    // Recreates the table
    private static void Recreate()
    {
      using (var connection = new OracleConnection(ConnectionString)) {
        connection.Open();
        using (var command = connection.CreateCommand()) {
          command.CommandText = @"
            declare
              table_count binary_integer;
            begin
              select count(*) into table_count from sys.user_tables where table_name = 'TESTTABLE';
              if table_count > 0 then
                execute immediate 'drop table TestTable purge';
              end if;
              execute immediate 'create table TestTable(id nvarchar2(32) primary key)';
            end;";
          command.ExecuteNonQuery();
        }
        connection.Close();
      }
    }

    // Opens session sessionCount times,inserts insertCount rows in each session.
    private static void Insert(int sessionCount,int insertCount)
    {
      for (int sessionNumber = 0; sessionNumber < sessionCount; sessionNumber++)
        using (var connection = new OracleConnection(ConnectionString)) {
          connection.Open();
          using (var transaction = connection.BeginTransaction(IsolationLevel.Serializable)) {
            for (int insertNumber = 0; insertNumber < insertCount; insertNumber++)
              using (var command = connection.CreateCommand()) {
                command.BindByName = true;
                command.CommandText = "insert into TestTable (id) values(:id)";
                var id = Guid.NewGuid().ToString("N");
                var parameter = new OracleParameter("id",OracleDbType.NVarchar2) {Value = id};
                command.Parameters.Add(parameter);
                command.Transaction = transaction;
                command.ExecuteNonQuery();
              }
            transaction.Commit();
          }
          connection.Close();
        }
    }

    static void Main(string[] args)
    {
      int iteration = 0;
      while (true) {
        Console.WriteLine("Running iteration: {0}",iteration);
        try {
          Recreate();
          Insert(10,100);
          Console.WriteLine("No error");
        }
        catch (Exception exception) {
          Console.WriteLine(exception.Message);
        }
        iteration++;
      }
    }
  }
}

代码运行无限循环。
在每次迭代时,它执行以下操作10次:@H_404_8@

>打开会话
>使用随机数据插入100行
>关闭会话
>显示一条消息,表示没有发生错误@H_404_8@

如果发生错误,则会捕获异常并打印其消息
那么执行下一个迭代。@H_404_8@

这里是示例输出。正如你所看到的那样,ORA-08177随机地与成功的交互进行交织。@H_404_8@

Running iteration: 1
No error
Running iteration: 2
ORA-08177: can't serialize access for this transaction
Running iteration: 3
ORA-08177: can't serialize access for this transaction
Running iteration: 4
ORA-08177: can't serialize access for this transaction
Running iteration: 5
ORA-08177: can't serialize access for this transaction
Running iteration: 6
ORA-08177: can't serialize access for this transaction
Running iteration: 7
No error
Running iteration: 8
No error
Running iteration: 9
ORA-08177: can't serialize access for this transaction
Running iteration: 10
ORA-08177: can't serialize access for this transaction
Running iteration: 11
ORA-08177: can't serialize access for this transaction
Running iteration: 12
ORA-08177: can't serialize access for this transaction
Running iteration: 13
ORA-08177: can't serialize access for this transaction
Running iteration: 14
ORA-08177: can't serialize access for this transaction
Running iteration: 15
ORA-08177: can't serialize access for this transaction
Running iteration: 16
ORA-08177: can't serialize access for this transaction
Running iteration: 17
No error
Running iteration: 18
No error
Running iteration: 19
ORA-08177: can't serialize access for this transaction
Running iteration: 20
No error

我正在运行Oracle 11.1.0.6.0并使用ODP.NET 2.111.6.20。
将隔离级别更改为ReadCommited修复了问题,但我真的想在Serializable级别运行此级别。
看起来像I’m not alone
有了这个问题,但答案没有给出,所以我再问一次。
我做错了什么,我该怎么解决这个问题?@H_404_8@

由APC编辑@H_404_8@

为了防止任何人咆哮错误的树,发布的代码示例只是ORA-8177错误生成器。显然实际代码是不同的;具体来说,丢弃和重建桌子是一个红色的鲱鱼。@H_404_8@

总重写(第一次出现错误的树)。

SERIALIZABLE隔离级别在“感兴趣的事务列表”中抓取一个插槽。如果Oracle无法获得一个插槽,那么它会引发ORA-8177。可用的ITL插槽的数量由INITRANS和MAXTRANS控制。根据the documentation:@H_404_8@

To use serializable mode,INITRANS
must be set to at least 3.@H_404_8@

必须为表及其索引设置此值。那么你的INITRANS设置是什么?当然,您的示例代码使用默认值(表为1,索引为2)。@H_404_8@

原文链接:https://www.f2er.com/oracle/206073.html

猜你在找的Oracle相关文章