【发布时间】:2021-09-24 10:31:55
【问题描述】:
我有一项服务应该计算用户登录的次数。如果我并行发出 3 个请求,我最终会在数据库中使用:
| Name | Requests |
|---|---|
| Jane | 1 |
| Jane | 1 |
| Jane | 1 |
代替
| Name | Requests |
|---|---|
| Jane | 3 |
名称不是主键。 睡眠仅用于演示目的,用于缓慢连接到数据库。
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public Long getRequestNumber(String name) {
UserEntity userEntity = userRepository.findByName(name);
if (userEntity == null) {
Thread.sleep(10000);
UserEntity userEntity = new UserEntity();
userEntity.setName(name);
userEntity.setReqNumber(1L);
userRepository.saveAndFlush(userEntity);
return 1L;
} else {
userEntity.setReqNumber(userEntity.getReqNumber() + 1);
userRepository.saveAndFlush(userEntity);
return userEntity.getReqNumber();
}
}
}
public interface UserRepository extends JpaRepository<UserRepository, Long> {
UserEntity findByName(String name);
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "user")
public class UserEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "req_number")
private Long reqNumber;
}
稍后编辑:
这似乎可行,但如果有人有更好的主意,我很高兴?
public interface UserRepository extends JpaRepository<UserRepository, Long> {
@Lock(LockModeType.PESSIMISTIC_READ) @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "30000")})
UserEntity findByName(String name);
}
【问题讨论】:
-
这种行为并不奇怪,因为您在插入新的 UserEntity 之前睡了 10 秒
-
睡眠仅用于演示目的
-
我明白这一点。即使没有睡眠,这种行为也可能偶尔发生
-
您应该查看隔离级别的概念,并确定这些限制与您的要求之间的关系。
-
我试过公共接口 UserRepository extends JpaRepository
{ @Lock(LockModeType.PESSIMISTIC_READ) @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = " 3000")}) UserEntity findByName(String name); }
标签: java jpa spring-data-jpa spring-data