【发布时间】: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 年的旧表模式 :)
标签: java oracle concurrency plsql