|
|
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
Такая проблема. ConcurrentHashMap<Integer, Session> теряет элементы. Дело в том, что с ним работает несколько потоков, какие-то пишут, какие-то читают, а какие-то удаляют элементы. В качестве ключа выступает id сессии из БД. Ключ уникален(автоинкриментное поле). При удалении так же удаляется запись из БД. Но вот проблема! По истечении некоторого времени, по неизвестной причине сессия сохраняется(запись в БД и само подключение клиента), а в HashMap его уже нет. В чем может быть проблема? Спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 15:43 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
Проблема в том что ConcurrentHashMap никак не участвует в транзакции на уровне БД. Поэтому очевидно, что так просто гарантировать консистентность состояние в БД и ConcurrentHashMap нельзя. Тем более в многопоточной среде. Для начала можно релизовать логирование чтобы точно знать что когда и куда записано и удалено. Вероятность того что ConcurrentHashMap сама по себе что-то там теряет очень мала. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 15:52 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
BlazkowiczПроблема в том что ConcurrentHashMap никак не участвует в транзакции на уровне БД. Поэтому очевидно, что так просто гарантировать консистентность состояние в БД и ConcurrentHashMap нельзя. Тем более в многопоточной среде. Для начала можно релизовать логирование чтобы точно знать что когда и куда записано и удалено. Вероятность того что ConcurrentHashMap сама по себе что-то там теряет очень мала. Я понимаю и поэтому делаю так: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:00 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
Более того при выполнении метода LogHelper.logError, мне еще и письмо приходит на мыло. Но дело в том, что этого не происходит... Значит все нормально. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:01 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
Фишка в том, что этот метод removeSession вызывается при потере подключения Socket: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. Но при этом клиент может взаимодействовать с системой. Т.е соединение точно есть. Но из HOSTS_SESSIONS пропадает. Т.е get по ключу возвращает null ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:05 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
Сделайте меня это развидеть, пожалуйста. Полиморфизм? Первый раз слышу! Нужен ещё один SessionType? Не беда - скопипастим ещё один if блок. SQL Injection/binding variables/query cache... Да, ну это всё. Extract variable. Это где такое? Логирование? Только для ошибок. Если нет Exception-а, значит всё нормально и логировать незачем. Hub.SESSONS_COUNT--. В многопоточной системе? Really? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:13 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
GorloPavel , Ну как вам уже ответили, вероятность того, что это баг в ConcurrentHashMap, стремиться к нулю. А вот вероятность того, что это гонка у вас в коде, примерно 99,999%. Где именно сидит эта гонка мы не знаем, и знать не можем, так как вы нам показали только одно из мест, где идет работа с этой мапкой. Но в целом ваш код выглядит очень плохо с точки зрения многопоточности, и я даже с достаточно высокой вероятностью могу предположить следующее: 1) В методе removeSession вы сначала удаляете из базы, а потом удаляете из мапки (это мы видим в том коде, что вы дали). 2) А в методe addSession (или как он у вас называется?) вы сначала пишете в базу, а потом пишете в мапку. 3) Теперь следите за руками, поток 1 вызывает removeSession, поток 2 вызывает addSession, и так получается, что эти операции выполняются в следующем порядке: Поток 2: создать сессию; Поток 1: удалить сессию; Поток 1: Hub.USERS_SESSIONS.remove(id); Поток 2: Hub.USERS_SESSIONS.put(id, ...). Все, сессии в базе нет, а в мапке есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:19 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Я конечно понимаю. Но опыт приходит со временем. Если можно, то покажите как правильно. На самом деле String.format для запросов только в этом месте программы. Так везде CallableStatement или PreparedStatement. Hub.SESSONS_COUNT-- как ни странно работает нормально :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:19 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
cdtyjv, Сессию удалить может только сам поток сессии и put вызывает он же. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:24 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
GorloPavelЯ конечно понимаю. Но опыт приходит со временем. Половину этих вопросов нужно знать через год комерческого программирования на Java. GorloPavelЕсли можно, то покажите как правильно. Правильно писать короткие методы. Чтобы не вываливать простыню на форум, а четко понимать в каком методе может быть проблема. Правильно заменять if\else на полиморфизм, особенно если блоки схожие, то выносить общий код. Правильно использовать переменные а не вызывать один и тот же метод 4 раза подряд. Правильно писать понятный самодокументируемый код а не вводить читателя в ступор вот такими пируэтами: getPartner().setPartner(null); Правильно держать SQL запросы вне Java кода, либо использовать Query DSL. Правильно разбирвать проект на абстрактные слои, а не запускать SQL запросы откуда вздумается. Правильно использовать binding variable для параметров SQL запроса. Правильно логировать все изменения состояния с разным уровнем логирования, а не только Exception-ы. Правильно использовать фреймверки логирования, а не LogHelper, который везде вызывается, так что даже не понятно кто писал в лог. GorloPavelHub.SESSONS_COUNT-- как ни странно работает нормально :) Правильно изучить многопоточность и атомарные операции, прежде чем пытаться написать что-то пригодное для использования в многопоточной среде. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:33 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
GorloPavelcdtyjv, Сессию удалить может только сам поток сессии и put вызывает он же. Логируете все операции с session id и тогда по логу будет видно что происходило и почему для конкретного session id, который вы обнаруили в БД. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:34 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Спасибо за ответы. Замечания приняты. Но я все равно не пойму куда могут деться сессии из мапа в этом коде, если put и remove может выполнять только сам поток сессии. Логировать сейчас что-то очень проблемно. Сервис работает и его используют тысячи пользователей. Я просто погрязну в логах на вечно. Может все таки сделать так как вы посоветовали в моей предыдущей теме? Хотелось бы увидеть пример от гуру :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:46 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
GorloPavel , Что такое "сам поток сессии"? Например, у вас 1000 сессий. Что, к каждой постоянно привязан какой-то поток один единственный поток? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:47 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
GorloPavel, Не понятно как используется SESSONS_COUNT. Не понятно как вы локализовали проблему в removeSession. Почему другие методы исключены? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:50 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
cdtyjv, Это поток(Thread) сокета. В нем обрабатываются данные от клиента и к примеру при авторизации эта сессия добавляется в HashMap. При потере соединения сессия должна удалить себя из HashMap и БД. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:51 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
cdtyjv, Это поток(Thread) сокета. В нем обрабатываются данные от клиента и к примеру при авторизации эта сессия добавляется в HashMap. При потере соединения сессия должна удалить себя из HashMap и БД. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:51 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
GorloPavelЯ просто погрязну в логах на вечно. Зачем в них грязнуть? Пишите в файлы. Храните все файлы за последние несколько дней. Проблема выделить под это дело пару гигабайт HDD? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:53 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Потому что в других методах нет remove из HashMap. Только в этом методе . В остальных get и put. Про put я уже объяснил, что он тоже в этом потоке. Т.е сессия сама себя добавляет и сама себя удаляет при отключении. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:54 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
GorloPavelЭто поток(Thread) сокета. В нем обрабатываются данные от клиента и к примеру при авторизации эта сессия добавляется в HashMap. При потере соединения сессия должна удалить себя из HashMap и БД. Бляха-муха. Сокет сервер на коленке. Чем готовые решения не угодили-то? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:54 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
BlazkowiczGorloPavel, Не понятно как используется SESSONS_COUNT. Да просто чтобы знать сколько сессий активных. Ну и кикать их если достигнут лимит. Вот кстати как я их "порождаю" Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:56 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
BlazkowiczБляха-муха. Сокет сервер на коленке. Чем готовые решения не угодили-то? Так вышло. Уже ничего не поделать. Надо решать проблему в этом коде. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:59 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
getSessionId() возвращает final поле? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 16:59 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
BlazkowiczgetSessionId() возвращает final поле? Оно не меняется нигде. Только задается однажды(из БД) и все. Нет не final. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 17:03 |
|
||
|
Проблема с ConcurrentHashMap
|
|||
|---|---|---|---|
|
#18+
С каким типом сессий возникает проблема? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2014, 17:03 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38520663&tid=2127814]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
28ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
2ms |
| others: | 226ms |
| total: | 344ms |

| 0 / 0 |
