При проверке документации HSQLDB я обнаружил различные модели параллелизма. Кажется, MVLOCKS или MVCC должны помочь мне в этой ситуации.
С MVLOCKS проблема, кажется, все еще распространена, тогда как с MVCC она действительно работает. Я предполагаю, что с MVLOCKS это тоже должно работать, и я хочу понять, почему в данном случае это не так?
Я подготовил пример приложения, показывающего проблему https://github .com/fridewald/hsqldb-test
Он использует обычные сеансы гибернации, поскольку иначе мне не удалось воспроизвести проблемы.
Здесь вы видите, как я изменил настройки на mvlocks или mvcc в файле application.properties
Код: Выделить всё
# this does not work, it blocks the reads. Why?
spring.datasource.url=jdbc:hsqldb:mem:testdb;hsqldb.tx=mvlocks
# this works
#spring.datasource.url=jdbc:hsqldb:mem:testdb;hsqldb.tx=mvcc
Код: Выделить всё
@Component
@Service
public class SlowUpdates {
...
@Scheduled(fixedRate = 10000)
public void slowlyUpdatingLamps() {
new Thread(new Runnable() {
public void run() {
log.info("try to slow update");
try (
Session session = sessionFactory.openSession();) {
session.beginTransaction();
long now = System.currentTimeMillis();
CriteriaBuilder lCriteriaBu = session.getCriteriaBuilder();
CriteriaQuery lQuery = lCriteriaBu.createQuery(Lamp.class);
Root lRoot = lQuery.from(Lamp.class);
lQuery.select(lRoot).where(lCriteriaBu.equal(lRoot.get("numberOfLamps"), 3));
log.info("Lamp read with findById(1L):");
List lamps = session.createQuery(lQuery).getResultList();
for (Lamp l : lamps) {
l.setLastUpdated(now);
session.persist(l);
log.info(l.toString());
}
session.flush();
// Wait 5 seconds and keep transaction open
Thread.sleep(5000);
List lamps2 = session.createQuery(lQuery).getResultList();
for (Lamp l : lamps2) {
l.setLastUpdated(now);
session.persist(l);
log.info(l.toString());
}
session.getTransaction().commit();
log.info("Session end");
} catch (Exception e) {
log.error("Error in slowlyUpdatingLamps", e);
}
}
}).start();
}
}
Код: Выделить всё
public class FastReads {
...
@Scheduled(fixedRate = 500)
public void readLamps() {
log.info("try to fast read");
try (
Session session = sessionFactory.openSession();) {
session.beginTransaction();
session.setDefaultReadOnly(true);
log.info("Lamp read with findById(1L):");
Lamp lamp = session.get(Lamp.class, 1L);
log.info(lamp.toString());
session.getTransaction().commit();
} catch (Exception e) {
log.error("Error in readLamps", e);
}
}
}
При попытке аналогичного примера с двумя консолями sql в базе данных hsqldb mvlocks был ведет себя так, как ожидалось.
Подробнее здесь: https://stackoverflow.com/questions/790 ... -hibernate
Мобильная версия