當我在 2 個不同的事務中保存物件時,代碼中出現以下錯誤:
org.springframework.orm.ObjectOptimisticLockingFailureException:帶有識別符號[]的類[]物件:樂觀鎖定失敗;嵌套例外是 org.hibernate.StaleObjectStateException:行已被另一個事務更新或洗掉(或未保存的值映射不正確):[]
我一直在嘗試為例外撰寫測驗。但是,所有測驗都已通過。
我的測驗:
@Slf4j
@Rollback
@Transactional
@DataJpaTest
@ActiveProfiles({"test", "h2"})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Import(value = {
StatusService.class
})
class StatusServiceTest {
@Autowired
private RequestRepository repository;
@Autowired
private StatusService statusService;
private Request request;
private final UUID requestUID = UUID.randomUUID();
@BeforeEach
void setUp() {
request = new Request();
request.setRequestUID(requestUID);
repository.save(request);
}
@Test
void updateStatus() {
Request request1 = repository.findByRequestUID(requestUID);
Request request2 = repository.findByRequestUID(requestUID);
statusService.updateStatus(request1, "Done");
statusService.updateStatus(request2, "In_progress");
}
}
服務:
@Service
@Slf4j
@RequiredArgsConstructor
public class StatusService {
private final RequestRepository repository;
@Transactional
public void updateStatus(Request request, String status) {
// Some simple logic
request.setStatus(status);
repository.save(request); // The line with error
}
}
模型:
@Entity
@Getter
@Setter
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Request {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonIgnore
protected Long id;
protected UUID requestUID;
private String status;
// Some additional fields
@JsonIgnore
@Version
private Integer version;
}
我哪里錯了?如何撰寫觸發錯誤的測驗?
uj5u.com熱心網友回復:
@DataJpaTest包括@Transactional因此您的測驗在單個事務中運行。
但是對于單個事務,JPA 的一級快取可確保您始終獲得給定類和 id 的相同實體。這意味著request1并且request2實際上是同一個實體,并且僅發生一次重繪 將無法創建樂觀鎖定例外。
有兩種方法可以創建樂觀鎖定例外。
實際使用兩個或多個事務。
TransactionTemplate對此非常有用。您可以將加載放在request1第一個事務中,然后加載、修改、保存和重繪request2,然后修改、保存和重繪request1。如果您想讓它更接近生產中發生的情況,您可以啟動兩個執行緒來執行這些操作,并使用CountDownLatch確保它們以所需的順序進行。或者,您應該能夠通過加載請求、修改其版本屬性并重繪 事務來觸發所需的例外。這當然與生產中發生的情況相去甚遠,但正如所說,它應該觸發例外。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/511489.html
上一篇:在建構式中創建的模擬物件
