| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > Как загрузить BMP EJB из тяжелой храним процедуры? |
| Автор: Barvetal 2.12.2005, 13:39 |
| Всем привет! Такая ситуация: нужно написать BMP Entity Bean, который должен отображать некоторую статистику, но не вносит никаких изменений в базу. Отбор статистики производится в MS SQL базе некоторой функцией, которая возвращает числа статистики. Функция довольно тяжелая и отрабатывает на БД-сервере порядка 4-5 секунд. Чтобы было понятней, покажу обьявление функции из БД: CREATE FUNCTION dbo.fGetClientStat(@ClientID int, @StatType smallint); Предлагаю на суд всем вам, как я собираюсь это сделать. Скажите пожалуйста, правильно ли я собираюсь сделать, или можно лучше? Так вот, если написать энтити бин ClientStat, то его первичный ключ будет содержать два поля: clientID, statType. Сам же BMP будет содержать в своих свойствах класса цифры статистики. По правилам создания BMP, необходимо определить метод FindByPrimaryKey, который должен будет определить, есть ли статистика для указанного ключа (в данном случае, это поля clientID и statType). Затем необходимо определить метод ejbLoad для загрузки статистики в свойства класса. Таким образом, по технологии, в методе FindByPrimaryKey нужно вызывать функцию fGetClientStat, чтобы определить, есть ли статистика для этого набора параметров, и эту же функцию нужно повторно вызывать и в методе ejbLoad уже для загрузки. Что меня в этом случае смущает... Получается, тяжелая сиквельная функция будет вызываться два раза!! Что займет 10 секунд времени для пользователя, ожидающего статистики, и сьест на это время серверные ресурсы!! Как решить проблему, чтобы не вызывать сиквельную функцию два раза?? Я придумал такой вариант решения. Метод FindByPrimaryKey не лезет в базу вобще, и просто возвращает переданный в параметре первичный ключ. Метод же ejbLoad пытается загрузить статистику при помощи сиквельной функции, и, если не получается, возвращает javax.ejb.NoSuchEntityException. А этот эксепшн я уже буду перехватывать в сесионном бине, и выводить свое сообщение, что статистика не найдена. Таким образом, я буду вызывать сиквельную функцию один раз, а не два Скажите пожалуйста, нормальный ли вариант решения, или можно лучше? Всем заранее спасибо!! |
| Автор: Lerm 2.12.2005, 15:13 |
| Есть еще такой шаблон - "толстый первичный ключ", FatKey. Смысл подхода: первичный ключ - это некоторый класс, который на самом деле хранит в себе все данные (помимо идентифицирующей информации). Т.е. клиент создает пустой Key (только, скажем, с ID), вызывает метод ejbFindBy<что-то>, эта функция загружает всю информацию, заносит её в первичный ключ и возвращает клиенты. Затем, при вызове ejbLoad, данные из ключа (который можно получить через контекст бина) переносятся в поля бина. При этом данные, грузятся только один раз - это применимо не только к исходной проблеме, но и вообще - как метод оптимизации производительности (особенно это эффективно при вызове finder-ов, которые возвращают коллекцию - тогда можно загрузить информацию для многих объектов, вместо того чтобы потом в ejbLoad лазить в базу для каждого бина). Естественно, что у метода есть и недостатки - в качестве ключа необходимо использовать свой класс, нужно очень аккуратно работать с транзакциями (что иногда приводит к необходимости использовать специфичное для данного сервера приложений API), да и вообще - всё это нужно очень аккуратно реализовывать и смотреть как ведет себе конкретный сервер приложений. |
| Автор: Barvetal 7.12.2005, 15:10 |
| Вобщем, написал сесионный бин, и из него вызываю сиквел через jdbc. И никаких энтити бинов... |
| Автор: Lerm 7.12.2005, 15:18 |
| Самое правильное. |