forum.bitel.ru http://forum.bitel.ru/ |
|
Кэшируемые PreparedStatement http://forum.bitel.ru/viewtopic.php?f=19&t=7875 |
Страница 1 из 1 |
Автор: | Cromeshnic [ 25 мар 2013, 10:41 ] |
Заголовок сообщения: | Кэшируемые PreparedStatement |
Пишу 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 в разных потоках. |
Автор: | dimOn [ 25 мар 2013, 16:36 ] |
Заголовок сообщения: | Re: Кэшируемые PreparedStatement |
Не могут, они (dao) как правило создаются внутри каждого метода вебсервиса. |
Автор: | Amir [ 25 мар 2013, 16:39 ] |
Заголовок сообщения: | Re: Кэшируемые PreparedStatement |
В Dao передается sql.Connection, который тоже не любит, когда его используют сразу в нескольких потоках, особенно при транзакциях, поэтому каждому потоку - свой Connection - свой Dao. |
Автор: | dimOn [ 25 мар 2013, 16:47 ] |
Заголовок сообщения: | Re: Кэшируемые PreparedStatement |
Заранее отвечая на вопрос «зачем тогда кешировать» могу ответить «низачем», не нужно ничего кешировать. Вообще почти нигде не нужно кешировать, кроме случаев большого обращения подряд по одному и тому же запросу. cachePrepStmts=true в коннекте стоит если, то оно само постарается кешировать. Но для такого запроса это абсурд, т.к. создание статемента почти ничего не стОит относительно самого выполнения и общения с сервером. Я никогда не кеширую в таком случае и считаю это абсурдом и преждевременной |
Автор: | stark [ 25 мар 2013, 17:14 ] |
Заголовок сообщения: | Re: Кэшируемые PreparedStatement |
dimOn писал(а): Заранее отвечая на вопрос «зачем тогда кешировать» могу ответить «низачем», не нужно ничего кешировать. Мы проводили тесты. При кэшировании есть большой прирост производительности |
Автор: | dimOn [ 25 мар 2013, 17:16 ] |
Заголовок сообщения: | Re: Кэшируемые PreparedStatement |
Ну так случаи нужно конкретные учитывать. Производительность при SELECT FROM один объект, как выше в примере, сильно вырастает? Чего именно производительность может вырасти? И как замеряли? Создать в цикле 100500 статементов? Ок. |
Автор: | Amir [ 25 мар 2013, 17:32 ] |
Заголовок сообщения: | Re: Кэшируемые PreparedStatement |
cachePrepStmts=true в DBCP кэширует все PS по ключу-строке. При динамических запросах WHERE id IN (...), в каждом из 300 соединений пула набирается куча никому не нужных PS. А когда влючены серверные PS, они через какое-то время достигают лимита открытых PS в mysql (а PS при кэшировании через DBCP для mysql являются открытыми). |
Автор: | Amir [ 25 мар 2013, 17:38 ] |
Заголовок сообщения: | Re: Кэшируемые PreparedStatement |
Код: Вообще почти нигде не нужно кешировать, кроме случаев большого обращения подряд по одному и тому же запросу. Согласен. Кэширование PS необходимо далеко не везде.
|
Автор: | Cromeshnic [ 26 мар 2013, 08:07 ] |
Заголовок сообщения: | Re: Кэшируемые PreparedStatement |
Ок, спасибо за комментарии. Amir писал(а): В Dao передается sql.Connection, который тоже не любит, когда его используют сразу в нескольких потоках, особенно при транзакциях, поэтому каждому потоку - свой Connection - свой Dao. dimOn писал(а): Не могут, они (dao) как правило создаются внутри каждого метода вебсервиса. Вот например ru.bitel.bgbilling.kernel.module.server.service.ServiceServiceImpl использует ServiceManager, который extends AbstractIdDao<Service>, причём создаёт его при инициализации сервиса. |
Автор: | stark [ 26 мар 2013, 10:29 ] |
Заголовок сообщения: | Re: Кэшируемые PreparedStatement |
Cromeshnic писал(а): Ок, спасибо за комментарии. Amir писал(а): В Dao передается sql.Connection, который тоже не любит, когда его используют сразу в нескольких потоках, особенно при транзакциях, поэтому каждому потоку - свой Connection - свой Dao. dimOn писал(а): Не могут, они (dao) как правило создаются внутри каждого метода вебсервиса. Вот например ru.bitel.bgbilling.kernel.module.server.service.ServiceServiceImpl использует ServiceManager, который extends AbstractIdDao<Service>, причём создаёт его при инициализации сервиса. Сервисы могут использоваться и в конвертерах (надо загрузить много-много договоров, услуг из файла/сторонней базы данных) , там создается один сервис и много много раз используется . так в данном случае это оправдано. Вообще любую нашу Dao-ку могут использовать, по идее, так . |
Автор: | dimOn [ 26 мар 2013, 15:34 ] |
Заголовок сообщения: | Re: Кэшируемые PreparedStatement |
Нужно просто не допускать многопоточного использования и всё. Остальное — ок. |
Страница 1 из 1 | Часовой пояс: UTC + 5 часов [ Летнее время ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |