基本上就是标题所说的。我们有一些关键数据将在同一个函数中读取和更新,我们必须确保我们可以避免竞争条件。 @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
@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();
}
}