Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > 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
Самое правильное. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)