Я использую jpa с hibernate для извлечения объектов данных с базой данных MySql (InnoDB). Вот рабочий процесс моего приложения.
- Результаты пользовательских запросов
- Пользователь изменяет один из результатов
- База данных «инактивирует» текущую строку и выполняет вставку для нового значения
- После сохранения изменения запрашиваемые результаты обновляются, чтобы показать изменения.
Например:
1. Select * from example_table where example_type in(1,2,3,4,5) and status = "active"
2. При обновлении пользователя - "Update example_table set status = "inactive" where example_table_id = 123
"
3. Вставьте в example_table(...) values(.. user_new_value)
4. на обновление - Select * from example_table where example_type in(1,2,3,4,5) and status = "active"
Когда выполняется выбор обновления, он возвращает результаты. Однако строка, для которой было задано неактивное значение, по-прежнему возвращается в запросе на обновление, поскольку обновление не было полностью зафиксировано.
Поскольку я использую jpa и hibernate - стоит отметить, что я использую явно написанный запрос на обновление, а не entityManager.merge()
. Я делаю это, чтобы избежать выполнения оператора select, за которым следует оператор update. Раньше, когда я использовал entityManager.merge для выполнения своих обновлений, проблема со «старыми данными» встречалась НАМНОГО БОЛЬШЕ
То, что я ищу, это способ заставить мой запрос на выборку подождать, пока не будут выполнены все коммиты строк. Я использовал "SELECT...FROM..WHERE.. LOCK IN SHARE MODE
", но мне не повезло.
Иногда результаты возвращаются с правильными результатами ... а иногда нет. Мне просто нужен способ убедиться, что мой запрос на выборку «подождет» всех обновлений…
РЕДАКТИРОВАТЬ ЗДЕСЬ МОЙ JPA-HIBERNATE код ...
вот вызов jpa dao для оператора select, выполненный до и после обновления:
public List<Tracking_Prv_Reln> getFirstNetRelnsByTrackingIds_TrackingPrvReln(List<Long> trackingIdList){
Map<String, Object>namedParams = new Hashtable<String, Object>();
namedParams.put("TRACKING_ID_LIST", trackingIdList);
return getJpaTemplate().findByNamedQueryAndNamedParams("getFirstNetRelnsByTrackingIds_TrackingPrvReln", namedParams);
}
Вот именованный запрос, найденный в сущности:
@NamedQuery(name="getFirstNetRelnsByTrackingIds_TrackingPrvReln",
query="SELECT tpr FROM Tracking_Prv_Reln tpr WHERE tpr.tracking_Id IN (:TRACKING_ID_LIST) " +
"AND tpr.unassign_Dt_Tm >= NOW() ",
hints=@QueryHint(name="org.hibernate.cacheable", value="false"))
Вот оператор обновления, который принимает переданную сущность ("Tracking_Prv_Reln"):
public void inactivateRow_TrackingPrvReln(Tracking_Prv_Reln tpr){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String query = "UPDATE Tracking_Prv_Reln SET unassign_Dt_Tm = STR_TO_DATE('" + sdf.format(tpr.getUnassign_Dt_Tm()) + "', '%Y-%m-%d %H:%i:%s'), " +
"updt_Dt_Tm = STR_TO_DATE('" + sdf.format(tpr.getUpdt_Dt_Tm()) + "', '%Y-%m-%d %H:%i:%s'), source_Flag = " + tpr.getSource_Flag() +
" WHERE tracking_Prv_Reln_Id = " + tpr.getTracking_Prv_Reln_Id();
executeQueryString(query);
}
public void executeQueryString(final String string){
getJpaTemplate().execute(new JpaCallback(){
public Object doInJpa(EntityManager em)throws PersistenceException {
String queryString = string;
Query query = em.createQuery(queryString);
return query.executeUpdate();
}
});
}
Мой кеш запросов в спящем режиме включен ...