使函数可以安全访问数据库表的最佳方法?

时间:2018-10-01 13:34:54

标签: java spring hibernate tomcat jpa

基本上是标题所说的。我们有一些关键数据将在同一函数中读取和更新,因此必须确保避免出现竞争状况。 @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

1 个答案:

答案 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();
    }   
}