![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| pinansonoyon |
|
||||||||||
|
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 30.8.2009 Репутация: нет Всего: нет |
Привет, люди планеты Земля!
Появилась такая задача: есть базейка. В ней есть уникальный ключ, некий адрес клиента и поле для проверки (чего- станет ясно позднее). Создавалась она так:
И вот я подумал- а что если адреса клиентов обрабатывать в потоках? Но ведь потоки ломанутся в базу и возможна ситуация, при которой несколько потоков будут обрабатывать один и тот же адрес! Тогда я решил обмануть весь мир и сделать функцию в базе, которая бы блокировала базу, ставила бы в кортеже минусик, что показывало бы другим потокам, что адрес обрабатывается и его трогать не стоит. Родилась такая функция:
Сам текст проги такой:
Класс по обработке адресов из базы:
Ну чего сказать? В однопотоке-то оно работало, а в многопотоке начались глюки, как и предсказывали умные люди: то работает как надо, то работает так, как будто не существует никакой блокировки таблицы, то работает какой-то усредненный вариант из этих двух вариантов. Залез в литературу. Нашел информацию о синхронизации потоков при использовании общих ресурсов. Ну, решил попробовать, хотя многие моменты остались неясными. Изменения коснулись класса Main:
Итог оказался точно таким же, как и до синхронизации. Те примеры, которые показывались в литературе меня убедили в том, что решение проблемы, в общем-то, лежит в области синхронизации, но куда чего там вставить- не могу понять. Какие будут мысли и предложения? Всех заранее благодарю и поздравляю с Новым годом!!! Это сообщение отредактировал(а) pinansonoyon - 30.12.2009, 14:56 |
||||||||||
|
|||||||||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Это врядли. В базе данных по умолчанию должны быть внутренние блокировки, исключающие возможность одновременного редактирования данных разными клиентами или чтение данных, находящихся в процессе редактирования. Синхронизировать доступ к данным в клиентских приложениях бессмысленно, потому что к базе может быть подключено несколько независимых клиентов. Это сообщение отредактировал(а) COVD - 30.12.2009, 00:25 |
|||
|
||||
| Temdegon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 429 Регистрация: 11.10.2008 Где: Minsk Репутация: 7 Всего: 9 |
Логику блокировки я не понял вообще, как и не увидел в ней смысла.
В главном потоке выберите все адреса из базы, разбейте полученный список на столько частей, сколько у вас потоков и передайте каждую часть в свой поток. Зачем вам здесь нужно в каждом потоке подключаться к базе и что-то там пытаться блокировать? Может я не так понял, что вы хотите сделать? Можете подробнее описать задачу? |
|||
|
||||
| ivanovpv |
|
|||
![]() Варвар ![]() ![]() Профиль Группа: Участник Сообщений: 639 Регистрация: 26.1.2005 Где: Москва Репутация: 4 Всего: 28 |
А для чего существует механизм транзакций? Как нам говорит COVD, По сути это и есть механизм транзакций. Доступ к нему осуществляется на уровне Java посредством JTA. С точки зрения клиента блокировки предлагаемые автором бессмысленны, единственное чем надо озаботиться так это тем, чтобы не возник deadlock - когда 1 поток ожидает другого, а тот его. -------------------- Aut viam inveniam aut faciam |
|||
|
||||
| pinansonoyon |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 30.8.2009 Репутация: нет Всего: нет |
Привет, ребята! Спасибо, что откликнулись.
Значит, давайте сначало я вам расскажу что я знаю. Апдейт и инсерт команды в Постгри происходят так (во всяком случае, я так вычитал это). Сначало база получает команду добавить или обновить кортеж. Потом она производит действия, в соответствии с командой, но не обновляет базу, а держит обновленный кортеж во внутреннем представлении. Потом, если ничего не происходит (примерно так и написано, но не сказано- что значит ничего), обновленный кортеж заносится в базу данных. Если же происходит что-то (скорее всего, если его пытается обновить другой клиент), то обновляемый кортеж изменяется и только после этого добавляется в базу. Таким образом можно сделать вывод, что если кортеж находится еще во внутреннем представлении, то его могут изменять поочередно 2 или более клиентов. К чему это может привести? А это может привести к ситуации, при которой первичные изменения в кортеже даже не будут внесены в базу и никто вообще не узнает, что они были. Теоретически это возможно. Не доверять информации американской книжки у меня причин нет. На этот случай у Постгри есть мощный механизм блокировок. Там много разных видов этой блокировки, но мой такой:
Считается самым мощным и полным. Вот при нем и происходит та ситуация с блокированием, о которой писал COVD. Саму блокировку снимать не надо, она автоматом снимается после окончания, в данном случае, работы функции. Обмозговав все это, я сделал вывод, что надо блокировать кортежи или как-то их помечать. Иначе потоки будут их обрабатывать вместе. Через средства Постгри в многопотоке этого сделать не удалось. В литературе я часто сталкивался с утвержденями, что если есть общие ресурсы, то надо делать синхронизацию потоков. Но там примеры примитивные и касаются, в основном, работы с файлами. Исходя из потребностей моей задачи они неясные и бесполезные. Я попробовал буквально по лекалу это сделать, но не вышло. 2Temdegon >>В главном потоке выберите все адреса из базы, разбейте полученный список на столько частей, сколько у вас потоков и передайте каждую часть в свой поток. Хорошо, а как конкретно это сделать? как именно передать каждому потоку свой адрес? Это сообщение отредактировал(а) pinansonoyon - 30.12.2009, 15:32 |
|||
|
||||
| ivanovpv |
|
||||
![]() Варвар ![]() ![]() Профиль Группа: Участник Сообщений: 639 Регистрация: 26.1.2005 Где: Москва Репутация: 4 Всего: 28 |
В упор не понимаю, почему автор пытается изобрести велосипед. Есть же стандартные механизмы. Например в каждом потоке надо делать что-то такое:
При этом гарантируется, что следы работы другого потока не будут мешать данному потоку. -------------------- Aut viam inveniam aut faciam |
||||
|
|||||
| Temdegon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 429 Регистрация: 11.10.2008 Где: Minsk Репутация: 7 Всего: 9 |
Ну мало ли как. А как вы бы поступили, если нужно двум экземплярам одного класса передать два разных параметра? Можно в конструкторе, можно сеттером, можно еще что-нить придумать) |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |