Параллелизм - доступ к БД - PullRequest
1 голос
/ 07 мая 2011

Мне нужно обработать получение ожидающих записей и обновить их до состояния «InProcess» как единицу работы.Я хотел бы убедиться, что приведенный ниже код поддерживает параллелизм, и другие потоки ожидают обработки моего текущего потока.Каков наилучший способ добиться этого?

public Collection<Object> processPendingMessages() {
    Collection<Object> messages = null;
    //Retrieve pending messages
    messages = messageDAO.getPendingMessages(Direction.INBOUND);
    //Update pending messages to Inprocess
    if (messages!=null && messages.size()>0) {
        messageDAO.updateMessagesToInprocess(messages); 
    } 
    return messages;
}

Ваш вклад высоко ценится.Спасибо.

Ответы [ 3 ]

5 голосов
/ 07 мая 2011

Вы не хотите обрабатывать параллелизм DBAccess только на уровне jvm, используя (синхронизированный).В вашем случае доступ к базе данных, который не будет возможен при простой синхронизации на уровне jvm.Вам также необходимо обрабатывать параллелизм на уровне подключения к базе данных следующим образом.Вы не упомянули, какая реализация находится на вашем уровне DAO в отношении DBaccess, но как бы то ни было, следующие уровни изоляции для JDBC должны иметь смысл с вашей реализацией слишком независимо от того, является ли она (JDBC, JPA сHibernate или EJB и т. Д.).Прочитайте приведенные ниже уровни изоляции и определите, какой из них подходит для вашего приложения.Всего наилучшего в вашей реализации.

Уровни изоляции транзакции указывают, какие данные видны операторам внутри транзакции как единица транзакции.Эти уровни напрямую влияют на уровень одновременного доступа, определяя, какое взаимодействие возможно между транзакциями с одним и тем же целевым источником данных.

АНОМАЛИИ БАЗЫ ДАННЫХ

Аномалии базы данных генерируют результаты, которыекажутся неправильными, если смотреть из области действия одной транзакции, но они корректны, если смотреть из области действия всех транзакций.Различные типы аномалий базы данных описываются следующим образом:

Грязное чтение происходит, когда: Транзакция A вставляет строку в таблицу.Транзакция B читает новую строку.Транзакция А откатывается.Транзакция B могла выполнять работу с системой на основе строки, вставленной транзакцией A, но эта строка никогда не становилась постоянной частью базы данных.

Неповторяемые чтения происходят, когда: Транзакция A читает строку.Транзакция B меняет строку.Транзакция A читает ту же строку во второй раз и получает новые результаты.

Фантомные чтения происходят, когда: Транзакция A читает все строки, которые удовлетворяют предложению WHERE вSQL-запрос.Транзакция B вставляет дополнительную строку, которая удовлетворяет предложению WHERE.Транзакция A повторно оценивает условие WHERE и выбирает дополнительную строку.

УРОВНИ ИЗОЛЯЦИИ, КОТОРЫЕ ОБРАЩАЕТСЯ КАЖДЫЙ ИЗ АНОМОЛИЙ

JDBC_TRANSACTION_NONE Это специальная константа, указывающая, чтоДрайвер JDBC не поддерживает транзакции.

JDBC_TRANSACTION_READ_UNCOMMITTED Этот уровень позволяет транзакциям видеть незафиксированные изменения данных.На этом уровне возможны все аномалии базы данных.

JDBC_TRANSACTION_READ_COMMITTED любые изменения, сделанные внутри транзакции, не видны снаружи, пока транзакция не будет зафиксирована.Это предотвращает возможность грязного чтения.

JDBC_TRANSACTION_REPEATABLE_READ строки, которые считываются, сохраняют блокировки, так что другая транзакция не может изменить их, когда транзакция не завершена.Это запрещает грязные чтения и неповторяемые чтения.Фантомное чтение все еще возможно.

Таблицы JDBC_TRANSACTION_SERIALIZABLE заблокированы для транзакции, поэтому условия WHERE не могут быть изменены другими транзакциями, которые добавляют или удаляют значения из таблицы.Это предотвращает все типы аномалий базы данных.

Метод setTransactionIsolation можно использовать для изменения уровня изоляции транзакции для соединения.

0 голосов
/ 07 мая 2011

вы должны позволить базе данных обрабатывать параллелизм.

в вашем DAO вы можете выполнить запрос sql:

// works on oracle.
// query may differ depending on vendor
select * from test where id=? for update 

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

0 голосов
/ 07 мая 2011

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

...