在与交易相关的视图中语句的可见性?

时间:2011-09-12 14:12:55

标签: java oracle hibernate transactions

我对数据库视图中的数据可见性有疑问。 我使用Oracle。 我有一个表myscheme.users和一个表global.users(myscheme和global是方案) 全局方案中有一个“globalusers”视图,它合并了两个用户表。

我有一个java应用程序,它在myscheme.users表中插入一个新用户。之后,它在globalusers-view中查询新用户以加载新创建的用户。 因为所有这些都发生在同一个交易中。我的问题是,为什么新创建的用户在myscheme.user表中可见而在globalusers-view中不可见? 当事务关闭时,用户也处于globaluser-view。

我的应用程序在使用hibernate的JBoss 5中运行。

视图以这种方式定义:

CREATE OR REPLACE VIEW V_USERACCOUNT AS
    SELECT u.USERACCOUNT_ID,u.USERNAME,u.INITIALS,u.COMMONNAME,u.PASSWORD,'local' AS source
        FROM "USERACCOUNT" u
    UNION
        SELECT u1.USERACCOUNT_ID,u1.USERNAME,u1.INITIALS,u1.COMMONNAME,u1.PASSWORD 'global' AS source
        FROM GLOBAL."USERACCOUNT" u1

1 个答案:

答案 0 :(得分:2)

如果表中的INSERT和视图中的SELECT实际上是同一数据库事务的一部分(这必然意味着它们在同一个数据库会话中执行),新插入的行将在视图中可见(假设该行符合视图用于确定要显示的行的任何条件)。如果新用户不在视图中,则表示要么

  1. INSERTSELECT不属于同一个数据库事务,或者
  2. INSERT不足以使该行在视图中可用。也许还有一些其他的查找表在视图中加入,当您查询视图时,该行没有新行的数据,但稍后在事务中填充了查找。
  3. 您的代码中某处有一个错误,当您认为INSERT实际上没有发生时,或INSERT之后查询未发生或查询未实际发生时你发布的观点。
  4. 根据您的最新更新,似乎#1几乎肯定是问题所在。如果您有不同的DataSource,INSERT使用一个DataSource,而SELECT使用第二个DataSource,则这两个操作不会发生在同一个数据库事务中。它们可能发生在同一个应用程序服务器事务中 - 应用程序服务器可能正在创建分布式事务 - 但如果它不是相同的数据库事务,则您将无法看到未提交的更改。