【问题标题】:oracle two different sessionoracle 两个不同的会话
【发布时间】:2014-03-28 04:09:24
【问题描述】:

在我们的工作中,我们创建了两个 .net 监听器, 第一: 调用 oracle 存储过程,使用 insert into select 语法将大量数据插入表(table1): 插入table1 select c1,c2... from tbl2 inner join tbl3.... 然后我们使用显式提交;

第二个监听器: 调用oracle程序,通过listener1读取插入table1的数据

但我们注意到,即使插入到 table1 listener2 的记录也无法在同一时间看到该记录,即使使用了该提交。

我的问题是当我们使用 insert ...select 时 cmmit 是如何工作的? 这个问题与会话有关吗?当侦听器 1 会话结束侦听器 2 可以读取数据时?

请帮忙,

提前致谢。

【问题讨论】:

    标签: oracle session locking


    【解决方案1】:

    您使用了错误的术语...

    监听器是一个服务器应用程序,它监听传入的客户端请求并将其传递给数据库引擎。客户端未使用侦听器。

    会话与您可以看到的数据无关,事务是控制它的对象。

    Oracle 以一种非常清晰的方式工作 - 在事务提交后 - 所有新事务都可以看到它,并且已经存在的事务可以根据它的事务配置看到新内容..
    我建议您阅读有关该上下文中的隔离级别的信息
    http://msdn.microsoft.com/en-us/library/system.transactions.isolationlevel(v=vs.110).aspx

    默认情况下 - 提交事务的时刻(在 DB 中由 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 - 请确保在正确的区域创建事务范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      • 2013-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多