代码之家  ›  专栏  ›  技术社区  ›  anakin59490

弹簧引导-同一对象上的多线程

  •  0
  • anakin59490  · 技术社区  · 6 年前

    我在一个项目中工作,用CRUD选项管理联系人数据库

    我使用Java8和SpringBoot2.0.4版本

    更新->代码而不是图像

    @RestController
    @RequestMapping("/api")
    @CrossOrigin(origins = "http://localhost:4200", allowedHeaders="*")
    public class ContactController {
    
        @Autowired
        private ContactService contactService;
    
        /*---  Toute la liste  ---*/
        @GetMapping("/contact")
        public List<ContactDTO> getDestinataires() {
            return contactService.getContacts();
        }
    
        /* ------------------------- CRUD ----------------------- */
    
        // Creation contact
        @PostMapping("/contact/create")
        public boolean create(@Valid @RequestBody ContactDTO contact) {
            return contactService.create(contact);
        }
    
        // infos d'un contact
        @GetMapping("/contact/{id}")
        public ContactDTO read(@PathVariable Integer id) {
            return contactService.getContact(id);
        }
    
        // Maj contact
        @PutMapping("/contact/update")
        public boolean update(@RequestBody ContactDTO contact) {
            return contactService.update(contact);
        }
    
        // Maj contact
        @DeleteMapping("/contact/delete/{id}")
        public boolean delete(@PathVariable Integer id) {
            return contactService.delete(id);
        }
    
    }
    

    @Service
    public class ContactService extends CoreServices{
    
        private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ContactService.class);
    
        public boolean update(ContactDTO contactDTOFront) {
    
            logger.info("ContactService - start update method");
            try {
                // contrôle si contact existe
                setContact(getContactRepo().findByIdaicontact(contactDTOFront.getIdaicontact()));
                if (getContact() == null) {
                    return false;
                }
    
                // alimentation du bean hibernate par le bean dto.
                contactDTOFront.alimBean(this);
    
                // maj de la bdd
                if (getContactRepo().save(getContact()) == null) {
                    return false;
                }
    
            } catch (Exception ure) {
                logger.error("ContactService - Error update method: " + ExceptionUtils.getStackTrace(ure));
                return false;
            }
    
            return true;
        }
    

    所有bean(DTO和实体)都在CoreServices类中管理:

    public class CoreServices {
    
        @Autowired
        private ContactRepository contactRepo;
    
        // Bean Contact
        Contact contact = new Contact();
        ContactDTO contactDTO = new ContactDTO();
        List<ContactDTO> contactDTOList = new ArrayList<ContactDTO>();
        List<Contact> contactList = new ArrayList<Contact>();
    
        public ContactRepository getContactRepo() {
            return contactRepo;
        }
        public Contact getContact() {
            return contact;
        }
        public void setContact(Contact contact) {
            this.contact = contact;
        }
        public ContactDTO getContactDTO() {
            return contactDTO;
        }
        public void setContactDTO(ContactDTO contactDTO) {
            this.contactDTO = contactDTO;
        }
        public List<ContactDTO> getContactDTOList() {
            return contactDTOList;
        }
        public void setContactDTOList(List<ContactDTO> contactDTOList) {
            this.contactDTOList = contactDTOList;
        }
        public List<Contact> getContactList() {
            return contactList;
        }
        public void setContactList(List<Contact> contactList) {
            this.contactList = contactList;
        }
    

    为了设置Contact bean,我使用DTO对象中定义的“alimBean”方法。这个方法在我的服务中被调用。

     public void alimBean(CoreServices service) throws Exception {
    
    logger.info("ContactDTO - start alimBean method");
    service.getContact().setIdaicontact(this.getIdaicontact());
    service.getContact().setIdentifiant(this.getIdentifiant());
    service.getContact().setIdaisite(this.getIdaisite());
    service.getContact().setIdaitype(this.getIdaitype());
    service.getContact().setNom(this.getNom());
    service.getContact().setPrenom(this.getPrenom());
    service.getContact().setEmail(this.getEmail());
    service.getContact().setComment(this.getComment());
    service.getContact().setStatus(this.getStatus());
    service.getContact().setLocked(this.getLocked());
    service.getContact().setUserlock(this.getUserlock());
    service.getContact().setCreuser(this.getCreuser());
    service.getContact().setUpduser(this.getUpduser());
    
    // Gestion des dates STRING -> DATE
    
    logger.info("ContactDTO - end alimBean method");
    
    }
    

    现在,假设同时处理两个更新请求。它是如何工作的? 我读了一些关于“同步”的短裙,但它们对我来说有点困惑。我不知道这是否是最好的方法,我不想破坏所有代码,除非它是处理这种多线程情况的唯一解决方案

    我可以在代码中添加什么来确保第二个请求在第一个请求结束之前不会设置联系人对象。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Beno    6 年前

    例如,您应该只同步更新和删除操作 id 如果它是独一无二的。你可以使用我的库,但它在阿尔法版本,但它是测试和工作良好。 必须添加依赖项:

    <dependency>
      <groupId>com.jsunsoft.util</groupId>
      <artifactId>concurrent</artifactId>
      <version>0.0.1-alpha2</version>
    </dependency>
    

    像这样写代码

    import com.jsunsoft.util.concurrent.locks.Lock;
    
    public class ContactService extends CoreServices {
      private final Lock contactLock = new StripedLock(minimumNumberOfStripes, lockTimeSec);
    
    public boolean update(ContactDTO contactDTOFront) {
        logger.info("ContactService - start update method");
        try {
            updateSynched(contactDTOFront);
        } catch (Exception ure) {
            logger.error("Co: " + ExceptionUtils.getStackTrace(ure));
            return false;
        }
        return true;
    }
    
    //you can add the method updateSynched
    private void updateSynched(ContactDTO contactDTOFront) throws Exception {
        contactLock.lock(contactDTOFront.getId(), () -> {
            setContact(getContactRepo().findByIdaicontact(contactDTOFront.getIdaicontact()));
            if (getContact() == null) {
                throw new Exception("msg");
            }
            // alimentation du bean hibernate par le bean dto.
            contactDTOFront.alimBean(this);
            // maj de la bdd
            if (getContactRepo().save(getContact()) == null) {
                throw new Exception("msg");
            }
        });
    }
    }