我正在运行一个创建一个表然后插入一些数据的程序。
这是访问数据库的唯一程序。
我随机得到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次:
>打开会话
>使用随机数据插入100行
>关闭会话
>显示一条消息,表示没有发生错误
这里是示例输出。正如你所看到的那样,ORA-08177随机地与成功的交互进行交织。
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
有了这个问题,但答案没有给出,所以我再问一次。
我做错了什么,我该怎么解决这个问题?
由APC编辑
为了防止任何人咆哮错误的树,发布的代码示例只是ORA-8177错误的生成器。显然实际代码是不同的;具体来说,丢弃和重建桌子是一个红色的鲱鱼。
总重写(第一次出现错误的树)。
SERIALIZABLE隔离级别在“感兴趣的事务列表”中抓取一个插槽。如果Oracle无法获得一个插槽,那么它会引发ORA-8177。可用的ITL插槽的数量由INITRANS和MAXTRANS控制。根据the documentation:
To use serializable mode,INITRANS
must be set to at least 3.
原文地址:https://www.jb51.cc/oracle/206073.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。