如何解决事务隔离无并发读取相同数据
我需要您的帮助来解决一个问题。目前,我的数据库中有很多用户,并且必须为这些用户分配 lastName (仅一次)。
如果 last_name 列为空,那么我将首先从数据库中提取此类记录并为其分配 last_name (更新用户记录)并更新到数据库中。
为了获得第一条这样的记录,我在 UserDetailsService.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();
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。