Ejb-кеш с синглтон-реализацией - PullRequest
1 голос
/ 24 марта 2012

Буду признателен за совет по поводу возникшей у меня проблемы.

Я работаю с jboss, средой EJB 3.1.

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

следующие запросы отправляются из пользовательского интерфейса:

1. refreshTree - a trigger for building the tree
2. isTreeReady - indicating whether the tree is ready to use, and called every x amount of time
3. getTree - return the tree.

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

Я думал о реализации его в качестве кэша следующим образом:

@singleton
public class TreeCache{

@EJB
MyTree tree;

boolean isTreeReady = false;

@Lock(LockType.WRITE)
public void refresh(){
      isTreeReady = false;
      tree = calulcateTree() \\ heavy calculation
      isTreeReady = true;
}

public boolean isTreeReady(){
      return isTreeReady;
}

public MyTree getTree(){
      return tree;
}

}

проблема, которая у меня естьэто может быть сценарий, в котором:

  1. первый пользователь обновляет дерево - и дерево строится.
  2. затем второй пользователь начинает строить дерево и инициализироватьфлаг isReady в false до того, как первый пользователь заметил о расчете дерева - в этом случае первому пользователю потребуется дождаться завершения вычисления (даже если бы он мог использовать дерево).

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

ВыУ меня есть идея, что я могу сделать?

спасибо.

1 Ответ

1 голос
/ 28 марта 2012

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

Но вы явно применили блокировку для метода refresh (), поэтому другие пользователи могут одновременно получать доступ к другим методам - ​​isTreeReady(), getTree() и т. Д. Поэтому, если вы удалите блокировку для метода refresh(), только один пользователь сможет одновременно получить доступ к методу.

  • LockType.READ: Аннотируйте бизнес или метод тайм-аута с помощью @Lock (LockType.READ), если к методу можно одновременно обращаться или совместно использовать его со многими клиентами.

  • LockType.WRITE: аннотируйте бизнес или метод тайм-аута с помощью @Lock (LockType.WRITE), если bean-компонент синглтона должен быть заблокирован для других клиентов, пока клиент вызывает этот метод.

Иначе, вы можете получить лучший контроль, используя параллелизм менеджера бинов, используя аннотацию @ConcurrencyManagement(ConcurrencyManagementType.BEAN) на одноэлементном бине. Но вы должны сами управлять синхронизацией методов, параллелизмом.

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

...