Как синхронизировать Java-метод, вызываемый PL / SQL

1

У меня просто проблема относительно параллелизма, логический поток которого, когда клиент (называемый Oracle Forms) отправляет запрос (называемый параллельной программой) и вызывает процедуру plsql, эта процедура в конечном итоге вызовет статический метод java.

Я нахожу, что когда я отправляю два запроса в одно и то же время или в очень короткий промежуток времени (например, 1 секунду), некоторые проблемы параллелизма будут замечены.

Метод java является отправной точкой для выполнения того, что поиск из базы данных подсказывает, какие записи следует вставлять в базу данных.

Проблема в том, что они приведут к дублированному результату, поскольку, когда я запрашиваю, оба запроса найдут все возможное, чтобы вставить новые записи.

Я попытался добавить synchronized в статическом java-методе, но это не решает эту проблему, почему?

Что я делаю:

public static synchronized void execute

Обратите внимание, что вставка будет вызываться в plsql, что означает, что я выполняю недостаточную синхронизацию, если только синхронизирую метод java. Но когда я заглядываю в журнал, он показывает два прогона запроса за ту же секунду, что я не думаю, что это нормально! поскольку база запросов и выполнение этого предложения занимает много времени.

Чтобы сделать Java-метод действительно трудоемким, я добавляю кодовый вызов Thread.sleep(5000) и регистрирую время после этого кода и регистрирую идентификатор потока.

Сюрприз, чтобы увидеть, что Thread идентификатор 1! А также время, когда они проходят сон в одно и то же время. Почему это?

Что я могу сделать для решения проблемы? Любая блокировка java-метода или pl sql?

PS: Теперь я пытаюсь использовать DMBS_LOCK и, похоже, работает, но я все еще надеюсь узнать причину, по которой метод java не синхронизирован.

  • 0
    Есть что-то, что вы пробовали?
  • 0
    сейчас я пытаюсь использовать dbms_lock для синхронизации процедуры plsql. Но я все еще надеюсь узнать, почему это не сработало.
Теги:
plsql
concurrency
oracleforms

2 ответа

2
Лучший ответ

Я понятия не имею, как реализована JVM внутри БД Oracle, но поскольку (по крайней мере, в некоторых общих конфигурациях) каждое соединение с базой данных получает свой собственный серверный процесс, то, если в каждую из них встроена отдельная JVM, Т ты много хорошего. Вам нужно будет использовать блокировки базы данных.

  • 0
    « Каждое соединение с базой данных получает свой собственный серверный процесс » - я не ожидал
0
  1. Предполагая, что вызовы статического метода Java выполняются внутри одного и того же загрузчика классов, synchronized - это все, что вам нужно.

  2. Возможно, ваш журнал неисправен. Как именно вы регистрируетесь?

  3. Ваше утверждение о том, что поиск базы данных "занимает много времени", не является убедительным. Базы данных, как правило, кэшируют данные, например.

В двух словах: если по вашему определению "атомарная операция" представляет собой комбинацию lookup + insert, вам следует "синхронизировать" по обоим. Приобретение блокировки базы данных выглядит разумным способом.

  • 0
    Для пункта № 3 я добавляю Thread.sleep (5000), чтобы он действительно занимал много времени. Но в итоге получается один и тот же результат, и я вижу оба запроса, используя идентификатор потока 1!
  • 1
    @Jaskey Thread#sleep не гарантирует, что текущий поток будет спать X миллисекунд, возможно, контроллер потока (в данном случае, ваша Oracle RBDMS) может отправить сигнал прерывания и разбудить поток, чтобы избежать этой наивной задержки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню