在我们的工作中,我们创建了两个.net监听器, 第一: 调用oracle存储过程,使用insert into select语法将大量数据插入表(table1): 插入table1从tbl2内连接tbl3中选择c1,c2 ... 然后我们使用表达式提交;
第二个听众: 调用oracle过程,通过listener1
读取插入table1的数据但是我们注意到即使插入到table1 listener2中的记录也无法在使用提交的同时看到该记录。
我的问题是当我们使用insert ... select时cmmit如何工作? 这个问题与会话有关吗?当监听器1会话结束监听器2可以读取数据?
请帮忙,
提前谢谢。
答案 0 :(得分:0)
你使用错误的条款......
侦听器是一个服务器应用程序,它侦听传入的客户端请求并将其交给数据库引擎。客户端没有使用监听器。
会话与您可以看到的数据无关,事务是控制该数据的对象。
Oracle以非常明确的方式工作 - 事务提交后 - 所有新事务都可以看到它,并且现有事务可以根据事务配置查看新内容。
我建议您阅读该上下文中的隔离级别http://msdn.microsoft.com/en-us/library/system.transactions.isolationlevel(v=vs.110).aspx
默认情况下 - 提交事务的时刻(在数据库中由SCN定义) - 数据对客户端可见。
底线 - 您的问题与事务隔离级别(在提交之前启动读取事务的情况)或编写器相关,编写器在您认为时不会提交数据(事务问题)。
在.net中调用transaction.Commit()返回后 - 数据已经可见,其他交易正在看到它。
你的第二个问题是提交是如何运作的
这是Oracle中一个非常复杂的过程,因此我将给出一个非常简短的描述:
1.提交时,Oracle首先在提交本身之前运行一些验证(例如,运行延迟约束)
2. oracle知道它可以安全地提交更改后获得系统时间(SCN),将提交本身写入重做日志,并将数据刷新到磁盘(为了保持一致性)。
3.向用户发送ACK,确认数据已为全世界所见
4.标记缓冲区被用作免费。
我要添加的东西,只是为了确保(我写了半个睡眠 - 所以请原谅我,如果它不编译...) 在您的.net代码中 - 您的代码应该在逻辑上等同于它:
OracleConnection con = new OracleConnection(connStr);
con.Open();
OracleTransaction trans = con.BeginTransaction();
OracleCommand cmd = con.CreateCommand();
cmd.Connection = cmd;
cmd.CommandText = "insert into ...";
cmd.ExecuteNonQuery();
cmd.Dispose();
trans.Commit();
trans.Dispose();
con.Close();
con.Dispose();
如果你正在使用LINQ - 请确保在右侧区域创建交易范围。