事务隔离无并发读取相同数据

问题描述

我需要您的帮助来解决一个问题。目前,我的数据库中有很多用户,并且必须为这些用户分配 lastName (仅一次)。 如果 last_name 列为空,那么我将首先从数据库中提取此类记录并为其分配 last_name (更新用户记录)并更新到数据库中。 为了获得第一条这样的记录,我在 UserDetailsS​​ervice.java 中使用findFirstByLastNameIsNull() [ Spring数据存储库]方法。我正在使用Insomnia(Rest Client)来运行Rest API。问题是,如果我在第37行放置了调试器(以模拟第一次休息调用时尚未完成第一个事务的条件,我将得到结果ID = 4,这是可以的..),当我第二次点击API时我得到相同的结果(db中的id = 4)。

我在第37行暂停了第一个请求后,我期望(id = 5)在第二次调用时会返回,因为第一个请求/事务未完成。但是每次返回时(id = 4)。我也尝试将隔离级别设置为序列化,但行为相同:(

想法位于测试网络中(并行),我们只需分配一次last_name。我们如何在这种情况下注意避免种族状况?

    package com.test.tx.management.service;

import com.test.tx.management.model.UserDetails;
import com.test.tx.management.repository.UserDetailsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@Transactional(isolation = Isolation.SERIALIZABLE)
public class UserDetailsService {
    @Autowired
    UserDetailsRepository userDetailsRepository;

    public UserDetails findFirstByLastNameIsNull() {
//        Optional<UserDetails> optionalUserDetails = userDetailsRepository.findFirstByLastNameEndingWith("ena");
        Optional<UserDetails> optionalUserDetails = userDetailsRepository.findFirstByLastNameIsNull();

        if (!optionalUserDetails.isPresent()) {
            return null;
        } else if (optionalUserDetails.get().getId() == 4) {
            UserDetails userDetails = optionalUserDetails.get();
            userDetails.setLastName("UserLastName 4");
            userDetailsRepository.save(userDetails);
            System.out.println("Halting when userid = 4,For First request...");
        }
        // Logic to update last_name here...
        return optionalUserDetails.get();
    }


    public void saveUserDetails(UserDetails userDetails) {
        userDetailsRepository.save(userDetails);
    }

    public UserDetails findUserDetailsById(Integer userId) {
        Optional<UserDetails> userDetailsOptional = userDetailsRepository.findById(userId);
        if (!userDetailsOptional.isPresent()) {
            return null;
        }
        return userDetailsOptional.get();
    }

    public int countUnAssignedLastName() {
        return userDetailsRepository.countByLastNameIsNull();
    }
}

####################

package com.test.tx.management.repository;

import com.test.tx.management.model.UserDetails;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface UserDetailsRepository extends JpaRepository<UserDetails,Integer> {
    //    Optional<UserDetails> findFirstByLastNameEndingWith(String startsWith);
    Optional<UserDetails> findFirstByLastNameIsNull();

    int countByLastNameIsNull();
}

enter image description here

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...