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

标签 java oracle concurrency plsql

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

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

我的 MyDatabse 有 1 个 shema 所有者和 10 个数据库用户被授权连接到它:
老板
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 Client Application 连接到 MyDatabase 的 DBUSERS。

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

DBUSER01 - call to my_package.getUser() returned EIS_ORA_200
DBUSER02 - call to my_package.getUser() returned EIS_ORA_200
DBUSER03 - call to my_package.getUser() returned EIS_ORA_200
DBUSER04 - call to my_package.getUser() returned EIS_ORA_200
DBUSER05 - call to my_package.getUser() returned EIS_ORA_200

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

  1. 在 DBUSERS 或之间共享 java 内存空间
  2. 为每个DBUSER分离内存空间

我的结论是,UserHandler 类是为每个 DBUSER 单独加载的,这就是我没有使用静态计数器和同步方法的原因。

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

非常感谢!

最佳答案

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

Oracle JVM model

Even when thousands of users connect to the server and run the same Java code, each user experiences it as if he is running his own Java code on his own JVM...

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

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

关于java - 如何在 Oracle 10g Java VM 中设置并发调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5179566/

相关文章:

java - Clojure/QuantLib 互操作 : classloading woes

java - GlassFish 重新启动 - 现在收到异常,将上下文初始化事件发送到类的监听器实例

sql - Oracle SQL进行连续分组

scala - Clojure 的代理与 Scala 的 Actor 相比如何?

java - 有没有办法在 Tomcat 中以编程方式将 SSL 设置为强制性的(例如,不通过 web.xml)?

oracle - 将 Oracle PL/SQL 转换为 Postgresql PL/pgSQL 的工具

c# - pl/sql 查询和 .net 的奇怪行为

c# - 由于版本列为空,无法保存实体。 NHibernate

java - Spring Cloud Stream 的 OUTPUT channel 的并发(线程执行器)

java - 从接口(interface)继承的spring注入(inject)bean