我已經像這樣在服務層中撰寫了一個更新方法,我使用 Spring-data JpaRepository 進行所有 CRUD 操作。
public Note updateNote(Note note, Long id) {
Note current = repository.getOne(id);
current.setTitle(note.getTitle());
current.setDetail(note.getDetail());
return repository.save(current);
}
我想對這個操作做一個樂觀鎖,所以我在Note物體中添加了一個版本欄位。
- 休眠會話如何影響版本資訊?版本比較實際上是如何發生的?
- 我嘗試通過使用多個執行緒的一些測驗來模擬這種情況,但無法這樣做并且無法驗證這是否有效。這種方法是對還是錯?如果物件處于分離狀態,樂觀鎖定會起作用嗎?或者是否有一些規則規定hibernate何時檢查新舊物體之間的版本匹配?
- 另外,我需要用@Lock注解顯式注解嗎?或者它會默認選擇 OPTIMISTIC_READ ?
uj5u.com熱心網友回復:
2:不,您不需要任何@Lock 來進行樂觀鎖定,使用@Version 我們實作了樂觀鎖定。
1:現在您可以使用執行緒測驗樂觀鎖定場景,下面我撰寫了一些示例測驗代碼,您可以根據您的要求進行更新。
假設我有 Note 物體:
@Entity
@Data
@ToString
public class Note {
@Id
@GeneratedValue
private Long id;
@Version
private int version;
private String name;
}
我也有用于執行資料庫操作的 Note Repository
@Repository
public interface NoteRepo extends JpaRepository<Note, Long> {
}
現在我有一個筆記服務
@Service
@AllArgsConstructor
public class NoteService {
private final NoteRepo noteRepo;
@Transactional
public Note create() {
Note note = new Note();
note.setName("Test Sample");
note = noteRepo.save(note);
System.out.println(note);
return note;
}
@Transactional
public void update(Long id, String name) {
Note note = noteRepo.getById(id);
note.setName(name );
note = noteRepo.save(note);
}
}
現在是時候使用集成測驗來測驗樂觀鎖定了。
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes =Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class TestServiceTest {
@Autowired
private NoteService noteService;
@Test
void assertObjectOptimisticLockingFailure() throws InterruptedException {
// Create a note, so after this we can perform updation
Note note = noteService.create();
//CountDownLatch required for wait test to complete
CountDownLatch countDownLatch = new CountDownLatch(2);
// Create 2 NoteThread to perform updation for exising note entity
NoteThread xNote = new NoteThread("X", note.getId(), countDownLatch);
NoteThread yNote = new NoteThread("Y", note.getId(), countDownLatch);
xNote.start();
yNote.start();
countDownLatch.await();
// Validate one of thread have ObjectOptimisticLockingFailureException
assertTrue(xNote.hasObjectOptimisticLockingFailure() || yNote.hasObjectOptimisticLockingFailure());
}
class NoteThread extends Thread {
private final String name;
private final Long id;
private final CountDownLatch countDownLatch;
private Class exceptionClass;
// verify exception
boolean hasObjectOptimisticLockingFailure() {
return this.exceptionClass == ObjectOptimisticLockingFailureException.class;
}
// Custome Thread class for performing note update and verify lock exception
public NoteThread(String name, Long id, CountDownLatch countDownLatch) {
this.name = name;
this.id = id;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
noteService.update(id, name);
} catch (Exception e) {
exceptionClass = e.getClass();
}finally {
countDownLatch.countDown();
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/461307.html
