2013-12-26 8 views
4

У меня есть клиент, который застрял в среде EJB 3.0. Нет @Singleton, не управляется bean-управляемым параллелизмом :-(Как реализовать кеш в ejb 3.0?

Учитывая, что управление потоком и синхронизация запрещены спецификацией ejb, как реализовать кеш? В сущности, я хочу несинхронизированный кеш объектов для некоторых дорогостоящих операций. !

+0

Не уверен, что я полностью понимаю segaste, но будут ли приложения cdi bean делать? –

+0

Нет, нет CDI в этой среде Java EE 5, и это не решит проблему синхронизации. Мне не нужен синглтон, просто @Singleton формирует ejb 3.1 + bean-managed параллелизм, который бы разрешил проблему. – ymajoros

+0

вы считали использовать безстоящий статус с максимальным значением пула = 1? –

ответ

0

я сомневаюсь, ясно или не понял ли я на ваш вопрос Следующий пример основан на weblogic и eclipselink

Если вы используете EclipseLink JPA для EJB, вы можете использовать кэш для каждого ваших сущностей отдельно, как это.:

@Entity 
@Cache(type=CacheType.SOFT) 

Если вы хотите, вы также можете включить кеширование для всех объектов из файла persistence.xml. Это будет, как это в поле свойства (oracle doc's link):

<persistence-unit name="XYZ"> 
... 
    <class>com.stack.Test</class> 
    <properties> 
     ... 
     <property name="toplink.cache.type.default" value="Soft"/> 
     ... 
    </properties> 
</persistence-unit> 

тип кэша может отличаться, как Soft, Hard, слабой, полная и т.д. Каждый из них оказывает свое собственное значение. Подробнее об этом типе кеша можно узнать от here.

+1

Ваш пример не зависит от weblogic (но будет работать только на eclipselink). Но это для сущностей JPA, и я ищу общий кэш. Кэш Eclipselink также будет кэшировать объекты с основным ключом в качестве ключа, чего в моем случае недостаточно. Я больше ищу универсальное решение проблемы с потоками. – ymajoros

0

Являются ли даже изменчивые переменные запрещенными в контейнере EJB? Изменчивая переменная int предоставляет некоторые гарантии, которые полезны для многопоточного кода. Если поток видит изменение изменчивой переменной, можно с уверенностью предположить, что он видит все, что было раньше.

Другой идеей будет объект @Stateful, который создается только один раз (вызовы будут сериализованы контейнером). Однако я не уверен в деталях реализации.

+0

Под «изменчивой переменной» вы подразумеваете нестабильное поле. Невозможно использовать в факторе без состояния. И у вас проблема атомарности. И это не решает проблему вообще: вам все еще нужен общий кэш, мой вопрос был о его реализации. Компонент сеанса с состоянием не зависит от вас и связан с государством. Таким образом, вы получите множество сессионных компонентов (по крайней мере, один сеанс пользователя). Спасибо за предложения, но они не отвечают на вопрос. – ymajoros

+0

Я хочу знать, как ты это сделал. Сообщите нам, когда вы закончите с каким-то образом. –

+0

Итак, у меня кончились идеи ... Возможно ли это? – marcus

1

Ограничение использования статического поля и синхронизации указано в главе 21.1.2 спецификации EJB 3.0. Это также объясняет, почему.

• Компонент предприятия не должен использовать статические поля чтения/записи. Использование разрешенных только для чтения статических полей. Поэтому рекомендуется, чтобы все статические поля в классе предприятия были объявлены окончательными.

Это правило необходимо для обеспечения последовательной семантики, потому что во время выполнения в то время как некоторые EJB-контейнеры могут использовать одну JVM для выполнения экземпляров все Enterprise Bean, другие могут распространять экземпляры на несколько виртуальных машинах.

• Компонент предприятия не должен использовать потоки синхронизации для синхронизации выполнения нескольких экземпляров .

Это по той же причине, что и выше. Синхронизация не будет работать , если контейнер EJB распределял экземпляры корпоративного компонента через несколько JVM.

При реализации кэша по одноплодной POJO, вы можете иметь риск того, что на самом деле существует несколько экземпляров кэша в каждом виртуальной машине Java, если EJB контейнер распределены экземпляры EJB в нескольких виртуальных машинах, например, в кластерной среде.

Так это зависит,

  • Если приложение не развернуто в кластере среде, вы могли бы сделать это. Насколько я знаю, WebLogic и GlassFish запускают один экземпляр сервера в одной JVM.
  • Если консистенция данных не ограничивается, вы также можете это сделать. Обычно это разрешено при разговоре о «кеше».

Если это не поможет вам, возможно, вам стоит подумать о кешировании данных вне контейнера EJB, например. положить в Redis или Hazelcast.

+0

Спасибо, что указали, почему это действительно интересно. Я предпочел бы придерживаться правила: не обрабатывайте синхронизацию самостоятельно. Вы не можете точно знать, что контейнеры будут играть с ним хорошо, и вы не сможете отлично протестировать, так как в редких случаях он может «провалиться» (= мертвая блокировка). Думаю, я просто пойду за непоследовательным, но не синхронизированным кешем. – ymajoros

0

Ну, я думаю, что ConcurrentSkipListMap может быть решением: нет синхронизации, но по-прежнему в потоковом режиме.

 Смежные вопросы

  • Нет связанных вопросов^_^