基本上是标题所说的。我们有一些关键数据将在同一函数中读取和更新,因此必须确保避免出现竞争状况。 @Transactional注释会解决这个问题吗?
// Both threads call this function
void someMethod() {
int value = EntityObject.getSomeField();
int newValue = modifyValue(value);
// PROBLEM: The other thread read "someField" before the database was updated,
// and we end up with the wrong value when both threads are done
EntityObject.setSomeField(newValue);
EntityObjectService.save(EntityObject);
}
我们正在使用MySQL
答案 0 :(得分:1)
@Transactional
注释将在数据库级别(而不是应用程序线程)帮助您。如果担心更新时旧数据不应被其他线程读取,我将使用ReentrantReadWriteLock
:
定义您的一种配置:
@Bean
public ReentrantReadWriteLock lock(){
return new ReentrantReadWriteLock();
}
在课程中更新时:
@Autowired private ReentrantReadWriteLock lock;
public void someMethod() {
try {
lock.writeLock().lock();
// Do your read & lengthy update here
} finally {
lock.writeLock().unlock();
}
}
当其他线程正在访问只读时:
@Autowired private ReentrantReadWriteLock lock;
public void someMethodThatReads() {
try {
lock.readLock().lock();
// Do your reading here
} finally {
lock.readLock().unlock();
}
}