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

我只是遇到了一个与并发相关的问题,其逻辑流程是当客户端(称为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方法不同步的原因。

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

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

  2. 您的日志记录可能有问题。 你到底记录了多少?

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

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