java - 在 Spring 中使用事务进行同步

标签 java mysql spring

我们有一个对MySql有读写的方法,这个方法可以被多线程调用。数据库操作如下:

public List<Record> getAndUpdate() {
    Task task = taskMapper.selectByPrimaryKey(id);
    if (task.getStatus() == 0) {
        insertRecords();
        task.setStatus(1);
        taskMapper.update(task);
    } 

    // some queries and return data
    return someRecordMapper.selectByXXX();
}

private void insertRecords() {
    // read some files and create someRecords
    someRecordMapper.insertBatch(someRecords);
}

该方法读取任务的状态,如果状态为 0,则将(该任务的)一堆记录插入 Records 表,然后将任务的状态设置为 1 .

我希望那些数据库操作是事务性的和独占的,这意味着当一个线程进入事务时,其他线程试图读取相同的 任务应该阻止。否则,他们会看到任务状态为 0,并且 insertRecords() 将被多次调用,从而导致数据重复。

@Transactional 注释似乎不会阻止来自其他线程的事务,它只确保在中止时回滚。所以我认为单独使用@Transactional,无法避免上述问题。

我用的是MySql和mybatis,我觉得MySql本身就可以实现这种线程间的同步,所以我尽量不引入redis锁等额外的组件来做。我想知道如何在 Spring 中执行此操作?

最佳答案

I 最终使用了 "SELECT ... FOR UPDATE" 查询。执行此查询后,所有其他读/写都将被锁定,直到当前事务提交或回滚。还需要用@Transactional注解方法。但是这里的行锁和事务是2个不同的关注点。测试结果令人满意。

关于java - 在 Spring 中使用事务进行同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55626970/

相关文章:

java - 读取 ZIP 文件会出现 'invalid LOC header' 异常

mysql - 读取、显示并插入到另一个表中

java - AOP:基本思想 - 保持对象简单?

Java倒排数组方法

php - 让 mySQL SUBSTRING 工作的小问题

java - 使用 requiresUnpack 使用 Maven 构建的 Spring Boot JAR 不起作用

Java Spring MVC - java.lang.NoClassDefFoundError : javax/servlet/ServletContext

java - 如何强制执行 Spring 配置类的加载顺序?

java - 在 Travis CI 上访问 mvnsearch.org 时如何避免 "The job exceeded the maximum time limit for jobs, and has been terminated."?

mysql - 生成 16M 唯一随机数