如何在 Oracle 10g Java VM 中设置并发调用

Posted

技术标签:

【中文标题】如何在 Oracle 10g Java VM 中设置并发调用【英文标题】:How to setup concurrent calls in Oracle 10g Java VM 【发布时间】:2011-03-03 10:36:54 【问题描述】:

如果有人可以解释我如何在不同的数据库用户调用相同的过程以确保正确的并发资源访问处理时正确配置 plsql java 包装器。

DBMS 和 JAVA:Oracle 10g,内部 JavaVM 1.4.2

我的 MyDatabse 有 1 个 shema 所有者和 10 个 db 用户被授权连接到它: 唐纳 DBUSER01 DBUSER02 ... DBUSER10

我有 PL/SQL 包装程序: 包装 UserHandler.getUser() 的 my_package.getUser()

我已经使用 loadjava 将 java 类 UserHandler 上传到 MyDatabase:

public class UserHandler 
    private static final int MAX_USER_COUNT = 10;
    private static final String USERNAME_TEMPLATE = "EIS_ORA_20";
    private static int currentUserSeed = 0;
    /**
    * Generates EIS user according to pattern agreed by EIS developers. It
    * circles user pool with round-robin method ensuring concurrent calls.
    * 
    * @return valid EIS USERNAME
    */
    synchronized public static String getUser() 
        String newUser = USERNAME_TEMPLATE + currentUserSeed;    
        currentUserSeed++;    
        currentUserSeed = currentUserSeed % MAX_USER_COUNT;    
        return newUser;    
        
    

包装器的想法是确保将外部信息系统用户名正确分配到使用 Oracle Forms 客户端应用程序连接到 MyDatabase 的 DBUSERS。

我的问题是当 5 个用户同时调用过程 my_package.getUser() 我得到:

DBUSER01 - 调用 my_package.getUser() 返回 EIS_ORA_200 DBUSER02 - 调用 my_package.getUser() 返回 EIS_ORA_200 DBUSER03 - 调用 my_package.getUser() 返回 EIS_ORA_200 DBUSER04 - 调用 my_package.getUser() 返回 EIS_ORA_200 DBUSER05 - 调用 my_package.getUser() 返回 EIS_ORA_200

我预计每个 DBUSER 都会获得不同的用户(正如我在多个并发线程调用 UserHandler.getUser() 的 JUnit 测试中确认的那样)。 后来我发现 plsql 包装器调用可以通过 2 种方式设置:

    在 DBUSERS 或之间共享 java 内存空间 为每个 DBUSER 分隔内存空间

我的结论是 UserHandler 类是为每个 DBUSER 分别加载的,这就是为什么我没有使用静态计数器和同步方法。

如何配置 MyDatabase 以强制调用 my_package.getUser() 为每个 DBUSER 使用相同的 java 空间?

非常感谢!

【问题讨论】:

有趣的问题,但是有什么原因你不能使用 pl/sql 函数并将当前用户种子存储在表中? oracle 开发人员拒绝用这种逻辑污染 20 年的旧表模式 :) 【参考方案1】:

我不相信有任何方法可以将 Oracle 配置为在多个用户会话之间共享 JVM。 10g 的 Java 开发人员指南指出:

Oracle JVM 模型

即使有成千上万的用户连接 到服务器并运行相同的 Java 代码,每个用户都像体验它一样 他正在运行自己的 Java 代码 自己的JVM...

通常,在 RDBMS 中的会话之间共享数据的适当方式是使用数据库对象。在这种情况下,最简单的方法是使用 Oracle 序列,最小值为 1,最大值为 10,并启用循环。您可以直接在 Java 代码中从序列中进行选择。

另一种方法是简单地在 1 到 10 之间生成一个均匀分布的随机数。如果有足够的会话,那么随着时间的推移,这应该均匀分布会话。

【讨论】:

最后我们用一个行表完成了。每个用户读取行进行更新,增加种子值并更新表中的值。

以上是关于如何在 Oracle 10g Java VM 中设置并发调用的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 JDBC 将 Java 存储过程加载到 Oracle 10g 中?

如何在 Oracle 10g DB 中重新编译 SYS 用户中的无效 Java 类对象?

oracle10g中,如何查询正则表达式匹配指定字符串的匹配个数?

java db browser 如何连接Oracle VM VirtualBox 的oracle数据库

如何在 Play 框架中执行查询(使用 Oracle 10g)

如何使用java在hibernate 3 + oracle中设置查询级别超时