Spring-webmvc 4.1.6 / Spring-data-jpa 1.7.2 / Oracle 12c
我的應用程式在 Netbeans 中以除錯模式在 localhost 上運行。我使用 jetty-maven-plugin 作為服務器并嘗試測驗使用 @Transactional 注釋的服務方法。
服務方法。
@Transactional("primaryTransactionManager")
@Override
public JsonResponseEntity<Dinero> Cancel_Deposit(Dinero dinero, EnumComportamientosDIN comportamiento_key, Boolean fromserver) {
dateUtils = new DateRangeUtils();
List<Dinerod> detalles = dinero.getDinerods();
for (Dinerod detalle : detalles) {
Dinero origen_depo = dineroRepository.findOneByAplica(detalle.getAplica(), detalle.getAplicaid());
BigDecimal saldo_actual = origen_depo.getSaldo();
BigDecimal importe_debitado = detalle.getImporte();
saldo_actual = saldo_actual.add(importe_debitado);
origen_depo.setSaldo(saldo_actual);
dineroRepository.save(origen_depo);
}
}
JPA 存盤庫
@Lock(LockModeType.PESSIMISTIC_WRITE)
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "30000")})
@Query("SELECT x FROM Dinero x WHERE x.mov = :aplica AND x.movid = :aplicaid")
Dinero findOneByAplica(@Param("aplica") String aplica, @Param("aplicaid") String aplicaid);
我不知道我的測驗方法是否錯誤,但它是以下內容:因為應用程式在本地主機上運行;從同一網路上的另一臺計算機,我模擬它是另一個人使用相同的應用程式。所以我同時在兩臺不同的計算機上運行相同的方法,試圖模擬一個事務崩潰。我嘗試用 PESSIMISTIC_WRITE 解決的同一個問題。
但是當我同時從兩臺不同的計算機上運行 web 表單時,資料庫中記錄的排他鎖定并沒有完成。
PESSIMISTIC_WRITE 會發生什么

是什么讓我頭疼

uj5u.com熱心網友回復:
我確信它作業得很好。
只需啟用 SQL 日志記錄,然后檢查執行的陳述句。它將包含 FOR UPDATE 子句,這意味著它作業得很好。
如果此功能不起作用,我自己為 Hibernate 撰寫的許多測驗將失敗,因此我懷疑 Hibernate 是否會發布不支持此功能的版本。
您無需使用 2 臺計算機運行它即可使其正常作業。你可以為它寫一個集成測驗,就像這個。
uj5u.com熱心網友回復:
我找到了問題的解決方案。正如您所說的 Vlad Mihalcea,在日志中我可以看到查詢包含 FOR UPDATE 子句,但我也注意到執行了 2 個查詢,第一個沒有 FOR UPDATE 子句,它是存盤在Entity Manager 1 級快取。第二個查詢是帶有 FOR UPDATE 的查詢。
因此,當 2 個事務同時到達時,它們會在快取中留下相同的物體,并對其值進行臟讀。
日志:
Hibernate: select dinero0_.ID as ID1_74_, dinero0_.IDCONCEPTO as IDCONCEPTO36_74_, dinero0_.ESTATUS as ESTATUS11_74_, dinero0_.FECHAEMISION as FECHAEMISION14_74_, dinero0_.MOV as MOV20_74_, dinero0_.MOVID as MOVID21_74_, dinero0_.SALDO as SALDO31_74_, from DINERO dinero0_ where dinero0_.MOV=? and dinero0_.MOVID=?
Hibernate: select ID from DINERO where ID =? for update wait 30
解決方案:
@PersistenceContext(unitName = "XUnitName")
private EntityManager em;
@Transactional("primaryTransactionManager")
@Override
public JsonResponseEntity<Dinero> Cancel_Deposit(Dinero dinero, EnumComportamientosDIN comportamiento_key, Boolean fromserver) {
dateUtils = new DateRangeUtils();
List<Dinerod> detalles = dinero.getDinerods();
for (Dinerod detalle : detalles) {
Dinero origen_depo = dineroRepository.findOneByAplica(detalle.getAplica(), detalle.getAplicaid());
em.refresh(origen_depo);
BigDecimal saldo_actual = origen_depo.getSaldo();
BigDecimal importe_debitado = detalle.getImporte();
saldo_actual = saldo_actual.add(importe_debitado);
origen_depo.setSaldo(saldo_actual);
dineroRepository.save(origen_depo);
}
}
我知道使重繪 顯式是因為物體管理器執行 2 個查詢,一個沒有 FOR UPDATE,另一個有 FOR UPDATE。
但我想知道為什么物體管理器不使用 FOR UPDATE 子句執行單個查詢。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/445648.html
