У меня проблема с производительностью транзакций записи JavaDB (Derby).Каждая транзакция занимает более 500 мс, и я мог бы иметь сотни тысяч в день.Я ожидаю развертывания на MySql и не знаю, возникнет ли там такая же проблема, но я пытаюсь улучшить производительность на Derby, прежде чем пытаться это сделать.
Одна транзакция включает обновление строкизаписей - целых 6 примерно так:
public void update(List<Tally> list) {
try {
utx.begin();
for (Tally tally : list) em.merge(tally);
utx.commit();
// etc
Я хотел посмотреть, будет ли запрос UPDATE работать лучше, поскольку JPA не придется отслеживать столбцы, которые обновляются, и составлять SQLзапрос (дополнительный вопрос: это хорошая теория?)
Итак, я закодировал именованный запрос, который выглядит следующим образом:
@NamedQuery(name="TallyUpdate",
query="UPDATE Tally t SET t.vote = t.vote + 1 WHERE t.id IN :idSet"
Он работает так:
@PersistenceContext protected EntityManager em;
@Resource protected UserTransaction utx;
public void incrementVote(List<Long> idList) {
Query q = em.createNamedQuery("TallyUpdate");
q.setParameter("idSet", idList);
try {
utx.begin();
q.executeUpdate();
utx.commit();
//etc
THE executeUpdate () вызов всегда вызывает исключение:
SEVERE: javax.persistence.TransactionRequiredException: executeUpdate is not supported for a Query object obtained through non-transactional access of a container-managed transactional EntityManager
at com.sun.enterprise.container.common.impl.QueryWrapper.executeUpdate(QueryWrapper.java:225)
Реализация JPA - EclipseLink 2.3.0
Что означает это исключение слова салатаи как я должен запустить обновление?
РЕЗУЛЬТАТ ПОСТАВКИ:
Я переместил вызов
createnamedQuery () после
utx.begin () звонок и обновление начало работать.Я не уверен почему, но я собираюсь бежать с этим пока.
Пока нет результатов относительно относительной производительности, но мои публикации выше вводят в заблуждение.Когда подсчитывается голос, он подсчитывается 24-36 различными способами, а не 6. Таким образом, существует шесть вызовов оригинального метода update () (который использует merge () ) каждыйсо списком около 6 записей.Именно эта коллекция вызовов занимает более 500 мс.Если таблица Tally пуста, то этот тест составляет всего около 27 мс, что соответствует скорости, которую я хотел бы видеть.Число 500 мс + - это то, что я вижу, когда таблица заполняется до 50 000 или более строк.
Если кто-то заинтересован в том, чтобы я опубликовал результаты, в которых я остановился на этом, пожалуйста, прокомментируйте так.
PS Это приложение JSF, работающее под GlassFish, а не EJB.Я не уверен, есть ли какие-либо последствия, связанные с производительностью.