java - 使访问数据库表线程安全的函数的最佳方法?

标签 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

最佳答案

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

关于java - 使访问数据库表线程安全的函数的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52592362/

相关文章:

java - org.hibernate.MappingException : Unknown entity: java. lang.Integer

java - 在 java 中使用 REST 调用模拟 cURL 时出错

spring - 多个数据源的 Hikaricp 配置

java - Mysql 连接 Spring Boot 困难

java - 转换为List后如何迭代方法中的元素?

java - 在 Spring MVC Hibernate 应用程序中,我应该在哪里保存用户图像?

java - hibernate是否默认使用PreparedStatement

java - 如何在 jackson 中跳过特定值的特定字段的序列化?

java - 使用android studio的gdax rest api请求

java - 带有 NBAandroid 的 NetBeans - 找不到符号 setContentView(R.layout.main);