如何同步PL / SQL调用的java方法

时间:2014-06-19 09:02:38

标签: java oracle concurrency plsql oracleforms

我只是遇到一个与并发相关的问题,其逻辑流程是当客户端(称为Oracle Forms)提交请求(称为并发程序)并调用plsql过程时,此过程最终将调用java静态方法。

我发现当我在同一时间或非常短的间隔(例如1秒)内提交两个请求时,会注意到一些并发问题。

java方法是做一些事情的起点,从数据库中搜索建议应该将哪些记录插入到数据库中。

问题在于,它们会导致重复的结果,因为当我查询时,两个请求都可以很好地插入新记录。

我尝试在静态java方法中添加synchronized,但这并不能解决这个问题,为什么呢?

我的工作是:

public static synchronized void execute

请注意,插入将在plsql中调用,这意味着如果只是同步java方法,我会进行不充分的同步。但是当我查看日志时,它会显示同一秒内运行的两个请求,我不认为这是正常的!因为查询数据库和做建议是耗时的。

为了使java方法非常耗时,我添加了一个代码调用Thread.sleep(5000),并记录此代码后的时间并记录线程ID。

惊喜地看到Thread id为1!此外,他们通过睡眠的时间也在同一时间。那是为什么?

我该怎么做才能解决问题?对java方法或pl sql的任何锁定?

PS:我现在正在尝试使用DMBS_LOCK,这似乎有效,但我仍然希望知道java方法未同步的原因。

2 个答案:

答案 0 :(得分:2)

我不知道Oracle DB中的JVM是如何实现的,但是因为(至少在一些常见配置中)每个数据库连接都有自己的服务器进程,那么如果嵌入了一个单独的JVM对于每一个,同步块不会对你有好处。您需要使用数据库锁。

答案 1 :(得分:0)

  1. 假设对Java静态方法的调用是在同一个类加载器中完成的,那么synchronized就是你所需要的。

  2. 您的日志记录可能有问题。你究竟是如何记录的?

  3. 关于数据库查找“耗时”的陈述并不令人信服。例如,数据库倾向于缓存数据。

  4. 简而言之:如果根据您的定义,“原子操作”是查找+插入的组合,那么您应该“同步”两者。获取数据库锁似乎是一种合理的方法。