【发布时间】:2022-01-12 10:01:52
【问题描述】:
我正在从数据库中读取一条记录并更新它,我有两种方法。 但是在这两个操作之间,我想在那个特定的行上获得一个锁,这样不同的线程就不会处理同一行。
这是我的存储库代码:
package com.anco.crud.repository;
import com.anco.crud.model.Employee;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
@Repository
public class EmployeeRepositoryImpl implements EmployeeRepository{
@Autowired
private EntityManager entityManager;
@Override
@Transactional
public Employee findEmpToProcessAndUpdateStatus() {
Session currentSession = entityManager.unwrap(Session.class);
String hql = "from Employee where status is null";
Query query = currentSession.createQuery(hql);
query.setMaxResults(1);
Employee employee = (Employee) query.uniqueResult();
System.out.println("FETCHED : " + employee.getFirstName());
employee.setStatus("INPROGRESS");
updateEmployee(employee);
return employee;
}
private boolean updateEmployee(Employee employee) {
try{
Thread.sleep(3000);
Session currentSession = entityManager.unwrap(Session.class);
currentSession.update(employee);
System.out.println("UPDATED : " + employee.getFirstName());
}catch (Exception e){
e.printStackTrace();
}
return true;
}
}
控制器代码:
@GetMapping("/employee/{mail}")
public boolean getAndUpdate() {
for(int i=0;i<5;i++){
Runnable rn = () -> process();
this.executor.execute(rn);
}
return true;
}
private void process() {
try {
Employee emp = employeeRepository.findEmpToProcessAndUpdateStatus();
} catch (Exception e) {
e.printStackTrace();
}
}
如果这不是正确的方法,那么更好的方法是什么?
【问题讨论】:
-
使用spring事务管理,注入entitymanager。将逻辑放入标记为
@Transactional的服务方法中,以便所有内容都在单个事务中执行。不要使用syncrhonized,因为那根本行不通。 -
嗨@M.Deinum,感谢您的回复。我已经更新了代码 sn-p ...所有线程都选择了具有相同邮件 ID 的员工
-
我说服务不是控制器,注释私有方法和内部方法调用都不起作用。您仍然需要在您的选择方法中选择更新,否则它将不起作用。
-
@M.Deinum,我再次更新了代码......仍然没有达到预期的效果
-
再一次你没有使用锁。另外,为什么要强制转换为
Session?只需使用EntityManager。在查询中使用setLockType(或者是setLockMode并使用您想要的。另外,您不需要调用更新,因为它是一个托管对象,它将自动持久化。
标签: java spring-boot hibernate jpa concurrency