Я разрабатываю систему учета с двумя записями, и мне нужно вставить записи проводок без пробелов в последовательном идентификаторе.Поскольку весь доступ к базе данных будет осуществляться через веб-приложение, я позабочусь о генерации идентификатора с использованием синхронизированной статической переменной:
import org.hibernate.*;
public class JournalService {
private static Object journalLock = new Object();
private Session session;
public JournalService(Session session) {
this.session = session;
}
public void insertJournalEntry(JournalEntry journalEntry) {
Set<PostEntry> entries = journalEntry.getEntries();
double total = 0;
for (PostEntry entry : entries) {
total += entry.getAmount();
}
if(total != 0)
throw new InvalidParameterException("Journal entry is invalid. The sum of all entries must be zero.");
Criteria criteria = session.createCriteria(PostEntry.class);
criteria.setMaxResults(1);
criteria.addOrder(Order.desc("id"));
//here I add some other criteria
synchronized(journalLock) {
PostEntry lastEntry = criteria.uniqueResult();
long currentId = lastEntry.getId();
for (PostEntry entry : entries) {
entry.setId(currentId++)
session.save(entry);
}
session.save(journalEntry);
}
}
}
В двух словах, срок службы этой службы связан с текущим httprequestуправляется пружинным контейнером, кроме того, я проверяю, что вся транзакция фиксируется в конце запроса.Синхронизированный блок позаботится о любом параллелизме, поэтому в последовательности идентификаторов не будет пробелов.Большая проблема здесь - это дополнительные издержки доступа к базе данных для выбора последней вставленной записи, которая соответствует определенным критериям.Я не хочу, чтобы это произошло, поэтому я предполагаю, что решение здесь заключается в использовании кэша, который будет хранить последнюю вставленную запись при первом ее выборе, поэтому для создания идентификатора не требуется доступ к базе данных.Мой вопрос: есть ли какой-нибудь спящий способ решения этой проблемы?Я новичок в спящем режиме и слышал о кеше запросов, но я не уверен, как его использовать.Я не хочу, чтобы в кеше хранились все значения, которые я сохраняю с помощью этого сервиса, мне просто нужно, чтобы он сохранял последнюю вставленную запись, которая соответствует определенным критериям.Например, если я выполнил пять вставок, две из которых соответствуют одинаковым критериям «X», а остальные три соответствуют критерию «Y», в кэше будут храниться только два объекта (последний вставленный объект, который соответствует каждому критерию).Я мог бы легко реализовать это сам, но я бы предпочел использовать решение, которое интегрируется с Hibernate API.