spring—多个使用者试图更新mysql(5.7版本)表的同一行如何修复并发更新问题

rdrgkggo  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(435)

多个使用者正在尝试更新jobtracker的“processedrecords”和“erredrecords”字段。但我面临的问题是,这些列中的随机值会更新。mysql处于默认隔离级别(mysql版本5.7)
我想用悲观的方法来锁定行。但下面的代码不会给出任何异常,而且行值也不会更新。请有人帮我解决这个问题。
请注意:1。任何改变整个数据库隔离级别的解决方案都没有帮助,因为它会影响应用程序中的其他流。2“processedrecords”和“erredrecords”都是long类型。

  1. @Override
  2. @Transactional
  3. public Boolean updateRecords(Long jobTrackerId, Long processedRecords, Long erredRecords) {
  4. try{
  5. JobTracker jobTracker = getEntityManager(true).find(JobTracker.class, jobTrackerId);
  6. getEntityManager(true).lock(jobTracker, LockModeType.PESSIMISTIC_WRITE);
  7. if(jobTracker == null){
  8. return false;
  9. }
  10. if(processedRecords!=null){
  11. jobTracker.setProcessedRecords(processedRecords);
  12. }
  13. if(erredRecords!=null){
  14. jobTracker.setErredRecords(erredRecords);
  15. }
  16. if(jobTracker.getErredRecords() != null && jobTracker.getProcessedRecords() != null && jobTracker.getTotalRecords() != null){
  17. if(jobTracker.getErredRecords() + jobTracker.getProcessedRecords() == jobTracker.getTotalRecords()){
  18. jobTracker.setStatus("Completed");
  19. }else if(jobTracker.getErredRecords() + jobTracker.getProcessedRecords() > jobTracker.getTotalRecords()){
  20. jobTracker.setStatus("Erred");
  21. }
  22. }
  23. getEntityManager(true).merge(jobTracker);
  24. return true;
  25. }catch(PersistenceException e){
  26. logger.error("For job id:" + jobTrackerId + " Exception while updating the jobTracker records data", e);
  27. return false;
  28. }catch (Exception e){
  29. logger.error("For job id:" + jobTrackerId + "Generic Exception while updating the jobTracker records data",e);
  30. return false;
  31. }
  32. }
sczxawaw

sczxawaw1#

使用@transactional注解,我们可以设置spring管理的事务方法的隔离级别。这意味着此方法中执行的事务将具有该隔离级别。在你的情况下,你所要做的就是以下几点。

  1. @Transactional(isolation=Isolation.READ_COMMITTED)

现在,如果要为整个数据库设置隔离级别,您可以执行以下操作。

  1. <property name="hibernate.connection.isolation">2</property>

相关问题