BiTel

Форум BiTel
bgbilling.ru     docs.bitel.ru     wiki.bitel.ru     dbinfo.bitel.ru     bgcrm.ru     billing.bitel.ru     bitel.ru    
Текущее время: 24 июн 2025, 17:47

Часовой пояс: UTC + 5 часов [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 11 ] 
Автор Сообщение
 Заголовок сообщения: Кэшируемые PreparedStatement
СообщениеДобавлено: 25 мар 2013, 10:41 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Пишу Dao для своей сущности, хочу кэшировать PreparedStatement-ы.
Смотрю по коду, как это правильно делается.
Например, ru.bitel.common.model.AbstractDao<B> :

Код:
  protected PreparedStatement getByIdPS = null;

  ...

  protected B getById(int id)
    throws BGException, SQLException
  {
    PreparedStatement ps = this.getByIdPS;
    if (ps == null)
    {
      ps = this.getByIdPS = this.con.prepareStatement("SELECT * FROM " + this.tableName + " WHERE id=?");
    }

    ps.setInt(1, id);

    ResultSet rs = ps.executeQuery();
    Object result;
    Object result;
    if (rs.next())
    {
      result = getFromRS(rs);
    }
    else
    {
      result = null;
    }
    rs.close();

    return result;
  }


А как быть с многопоточностью?
Разве не может возникнуть ситуация, когда между строчками
Код:
    ps.setInt(1, id);
    ResultSet rs = ps.executeQuery();

выполнится ps.setInt() из другого потока для того же ps ?
Может быть я что-то упускаю?
Например, веб-сервисы могут использовать один и тот же Dao в разных потоках.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Кэшируемые PreparedStatement
СообщениеДобавлено: 25 мар 2013, 16:36 
Не в сети
Аватара пользователя

Зарегистрирован: 30 май 2008, 15:51
Сообщения: 6055
Карма: 244
Не могут, они (dao) как правило создаются внутри каждого метода вебсервиса.

_________________
I'm clever. I've got a computer.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Кэшируемые PreparedStatement
СообщениеДобавлено: 25 мар 2013, 16:39 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
В Dao передается sql.Connection, который тоже не любит, когда его используют сразу в нескольких потоках, особенно при транзакциях, поэтому каждому потоку - свой Connection - свой Dao.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Кэшируемые PreparedStatement
СообщениеДобавлено: 25 мар 2013, 16:47 
Не в сети
Аватара пользователя

Зарегистрирован: 30 май 2008, 15:51
Сообщения: 6055
Карма: 244
Заранее отвечая на вопрос «зачем тогда кешировать» могу ответить «низачем», не нужно ничего кешировать.
Вообще почти нигде не нужно кешировать, кроме случаев большого обращения подряд по одному и тому же запросу. cachePrepStmts=true в коннекте стоит если, то оно само постарается кешировать. Но для такого запроса это абсурд, т.к. создание статемента почти ничего не стОит относительно самого выполнения и общения с сервером. Я никогда не кеширую в таком случае и считаю это абсурдом и преждевременной эяоптимизацией.

_________________
I'm clever. I've got a computer.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Кэшируемые PreparedStatement
СообщениеДобавлено: 25 мар 2013, 17:14 
Не в сети
Разработчик

Зарегистрирован: 08 ноя 2007, 01:05
Сообщения: 8343
Откуда: Уфа
Карма: 238
dimOn писал(а):
Заранее отвечая на вопрос «зачем тогда кешировать» могу ответить «низачем», не нужно ничего кешировать.

Мы проводили тесты. При кэшировании есть большой прирост производительности


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Кэшируемые PreparedStatement
СообщениеДобавлено: 25 мар 2013, 17:16 
Не в сети
Аватара пользователя

Зарегистрирован: 30 май 2008, 15:51
Сообщения: 6055
Карма: 244
Ну так случаи нужно конкретные учитывать. Производительность при SELECT FROM один объект, как выше в примере, сильно вырастает? Чего именно производительность может вырасти? И как замеряли? Создать в цикле 100500 статементов? Ок.

_________________
I'm clever. I've got a computer.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Кэшируемые PreparedStatement
СообщениеДобавлено: 25 мар 2013, 17:32 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
cachePrepStmts=true в DBCP кэширует все PS по ключу-строке.
При динамических запросах WHERE id IN (...), в каждом из 300 соединений пула набирается куча никому не нужных PS.
А когда влючены серверные PS, они через какое-то время достигают лимита открытых PS в mysql (а PS при кэшировании через DBCP для mysql являются открытыми).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Кэшируемые PreparedStatement
СообщениеДобавлено: 25 мар 2013, 17:38 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
Код:
Вообще почти нигде не нужно кешировать, кроме случаев большого обращения подряд по одному и тому же запросу.
Согласен. Кэширование PS необходимо далеко не везде.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Кэшируемые PreparedStatement
СообщениеДобавлено: 26 мар 2013, 08:07 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Ок, спасибо за комментарии.

Amir писал(а):
В Dao передается sql.Connection, который тоже не любит, когда его используют сразу в нескольких потоках, особенно при транзакциях, поэтому каждому потоку - свой Connection - свой Dao.

dimOn писал(а):
Не могут, они (dao) как правило создаются внутри каждого метода вебсервиса.


Вот например ru.bitel.bgbilling.kernel.module.server.service.ServiceServiceImpl использует ServiceManager, который extends AbstractIdDao<Service>, причём создаёт его при инициализации сервиса.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Кэшируемые PreparedStatement
СообщениеДобавлено: 26 мар 2013, 10:29 
Не в сети
Разработчик

Зарегистрирован: 08 ноя 2007, 01:05
Сообщения: 8343
Откуда: Уфа
Карма: 238
Cromeshnic писал(а):
Ок, спасибо за комментарии.

Amir писал(а):
В Dao передается sql.Connection, который тоже не любит, когда его используют сразу в нескольких потоках, особенно при транзакциях, поэтому каждому потоку - свой Connection - свой Dao.

dimOn писал(а):
Не могут, они (dao) как правило создаются внутри каждого метода вебсервиса.


Вот например ru.bitel.bgbilling.kernel.module.server.service.ServiceServiceImpl использует ServiceManager, который extends AbstractIdDao<Service>, причём создаёт его при инициализации сервиса.

Сервисы могут использоваться и в конвертерах (надо загрузить много-много договоров, услуг из файла/сторонней базы данных) , там создается один сервис и много много раз используется . так в данном случае это оправдано. Вообще любую нашу Dao-ку могут использовать, по идее, так .


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Кэшируемые PreparedStatement
СообщениеДобавлено: 26 мар 2013, 15:34 
Не в сети
Аватара пользователя

Зарегистрирован: 30 май 2008, 15:51
Сообщения: 6055
Карма: 244
Нужно просто не допускать многопоточного использования и всё. Остальное — ок.

_________________
I'm clever. I've got a computer.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 11 ] 

Часовой пояс: UTC + 5 часов [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
POWERED_BY
Русская поддержка phpBB
[ Time : 0.043s | 38 Queries | GZIP : On ]