Имплементирање на трансакции во апликацијата
Во неколку методи во контролерите се наоѓаа несигурни операции кои можеа да го загрозат интегритетот на базата. Имено постоеа повици за запишување во база едно по друго без никаква сигурност дека доколку вториот повик е неуспешен, првиот ќе се поништи, напротив со кодот којшто беше претходно поставен ќе се извршеше првото додавање, па доколку беше неуспешно второто, првото ќе останеше во база.
Со користење на моќната анотација во Spring Boot @Transactional и воведување на нови методи во сервисите се осигураме дека нема ништо вакво да се случи.
Пример 1
Кодот кој претходно изгледаше вака:
@PostMapping("/addPart") public void addPart(@RequestParam String name, @RequestParam(required = false) String description, @RequestParam Integer manufacturer, @RequestParam List<Car> cars, @RequestParam List<Category> categories, @RequestParam Integer warehouse, @RequestParam Integer quantity, @RequestParam Integer amount, HttpServletResponse response){ Part newPart = new Part(name, description==null ? "" : description, partManufacturerRepository.findById(manufacturer).get(), categories, List.of(warehouseRepository.findById(warehouse).get()),cars); partRepository.save(newPart); priceService.save(new Price(amount, LocalDate.now(),newPart)); partIsInStockInWarehouseRepository.save(new PartIsInStockInWarehouse(newPart.getId(),warehouse,quantity)); for (Category c:categories ) { partIsFromCategoryRepository.save(new PartIsFromCategory(newPart.getId(),c.getId())); } for (Car car:cars){ partIsAppropriateForCarRepository.save(new PartIsAppropriateForCar(newPart.getId(),car.getId())); } }
Сега изгледа вака :
@PostMapping("/addPart") public void addPart(@RequestParam String name, @RequestParam(required = false) String description, @RequestParam Integer manufacturer, @RequestParam List<Car> cars, @RequestParam List<Category> categories, @RequestParam Integer warehouse, @RequestParam Integer quantity, @RequestParam Integer amount, HttpServletResponse response){ partService.addPart(name,description,manufacturer,cars,categories,warehouse,quantity,amount); }
Со соодветен метод во сервисот :
@Transactional public void addPart(String name, String description, Integer manufacturer, List<Car> cars, List<Category> categories, Integer warehouse, Integer quantity, Integer amount) { Part newPart = new Part(name, description==null ? "" : description, partManufacturerRepository.findById(manufacturer).get(), categories, List.of(warehouseRepository.findById(warehouse).get()),cars); partRepository.save(newPart); priceService.save(new Price(amount, LocalDate.now(),newPart)); partIsInStockInWarehouseRepository.save(new PartIsInStockInWarehouse(newPart.getId(),warehouse,quantity)); for (Category c:categories ) { partIsFromCategoryRepository.save(new PartIsFromCategory(newPart.getId(),c.getId())); } for (Car car:cars){ partIsAppropriateForCarRepository.save(new PartIsAppropriateForCar(newPart.getId(),car.getId())); } }
Пример 2
Кодот кој претходно изгледаше вака:
@PostMapping("/addToOrder/{id}") public void addToOrder(@PathVariable Integer id,@RequestParam Integer quantity, HttpSession session, HttpServletResponse response, HttpServletRequest request){ if(session.getAttribute("order")==null){ User u = userService.findByUsername(request.getRemoteUser()); Order newOrder = orderService.create((Client) u); session.setAttribute("order",newOrder); } Order order = (Order) session.getAttribute("order"); orderContainsPartRepository.save(new OrderContainsPart(id,order.getOrderid(),quantity)); }
Сега изгледа вака :
@PostMapping("/addToOrder/{id}") public void addToOrder(@PathVariable Integer id,@RequestParam Integer quantity, HttpSession session, HttpServletResponse response, HttpServletRequest request){ if(session.getAttribute("order")==null){ User u = userService.findByUsername(request.getRemoteUser()); Order newOrder = orderService.createOrderAndAddPartToOrder((Client) u, id, quantity); session.setAttribute("order",newOrder); } else { Order order = (Order) session.getAttribute("order"); orderContainsPartRepository.save(new OrderContainsPart(id, order.getOrderid(), quantity)); } }
Со соодветен метод во сервисот :
@Transactional public Order createOrderAndAddPartToOrder(Client user, Integer partId, Integer quantity) { Order order = orderRepository.save(new Order(user)); orderContainsPartRepository.save(new OrderContainsPart(partId, order.getOrderid(), quantity)); return order; }
Пример 3
Кодот кој претходно изгледаше вака:
@PostMapping("/addCarSampleForUser") public void addCarSampleForUser(@RequestParam Integer vin, @RequestParam Integer year, @RequestParam Integer power, @RequestParam Integer displacement, @RequestParam String fuel, @RequestParam Integer km, @RequestParam Integer cartype, HttpServletRequest request, HttpServletResponse response){ CarSample cs = new CarSample(vin,year,power,displacement,fuel,km, (Client) userService.findByUsername(request.getRemoteUser()),carService.findById(cartype)); carSampleRepository.save(cs); serviceBookRepository.save(new ServiceBook(cs)); }
Сега изгледа вака :
@PostMapping("/addCarSampleForUser") public void addCarSampleForUser(@RequestParam Integer vin, @RequestParam Integer year, @RequestParam Integer power, @RequestParam Integer displacement, @RequestParam String fuel, @RequestParam Integer km, @RequestParam Integer cartype, HttpServletRequest request, HttpServletResponse response){ userService.addCarSampleForUser(vin,year,power,displacement,fuel,km,cartype,request.getRemoteUser()); }
Со соодветен метод во сервисот :
@Transactional public void addCarSampleForUser(Integer vin, Integer year, Integer power, Integer displacement, String fuel, Integer km, Integer cartype, String username) { CarSample cs = new CarSample(vin, year, power, displacement, fuel, km, (Client) this.findByUsername(username), carRepository.findById(cartype).get()); carSampleRepository.save(cs); serviceBookRepository.save(new ServiceBook(cs)); }
Пример 4
Кодот кој претходно изгледаше вака:
@PostMapping("/addRepairShop") public void saveRepairShop(@RequestParam String name,@RequestParam String location, @RequestParam String number,@RequestParam Integer carMId, HttpServletResponse response) { RepairShop newRs = new RepairShop(name,location,number, List.of(carManufacturerRepository.findById(carMId).get())); repairShopRepository.save(newRs); rsForCmRepository.save(new RsForCm(newRs.getId(), carMId)); }
Сега изгледа вака :
@PostMapping("/addRepairShop") public void saveRepairShop(@RequestParam String name,@RequestParam String location, @RequestParam String number,@RequestParam Integer carMId, HttpServletResponse response) { repairShopService.save(name,location,number,carMId); }
Со соодветен метод во сервисот :
@Transactional public void save(String name, String location, String number, Integer carMId) { RepairShop newRs = new RepairShop(name,location,number, List.of(carManufacturerRepository.findById(carMId).get())); repairShopRepository.save(newRs); rsForCmRepository.save(new RsForCm(newRs.getId(), carMId)); }
Пример 5
Кодот кој претходно изгледаше вака:
@PostMapping("/myWarehouse/{pname}") public void addPartToWarehouse(@PathVariable String pname,@RequestParam Integer quantity, HttpServletRequest request, HttpServletResponse response){ Integer pId = partRepository.findAllByName(pname).stream().findFirst().get().getId(); Warehouseman whm = (Warehouseman) userService.findByUsername(request.getRemoteUser()); Warehouse wh = whm.getWarehouse(); Integer whId = wh.getId(); PartIsInStockInWarehouseId tmp = new PartIsInStockInWarehouseId(pId,whId); PartIsInStockInWarehouse temp = partIsInStockInWarehouseRepository.findById(tmp).get(); temp.setQuantity(temp.getQuantity()+quantity); partIsInStockInWarehouseRepository.save(temp); }
Сега изгледа вака :
@PostMapping("/myWarehouse/{pname}") public void addPartToWarehouse(@PathVariable String pname,@RequestParam Integer quantity, HttpServletRequest request, HttpServletResponse response){ Integer pId = partRepository.findAllByName(pname).stream().findFirst().get().getId(); Warehouseman whm = (Warehouseman) userService.findByUsername(request.getRemoteUser()); Warehouse wh = whm.getWarehouse(); Integer whId = wh.getId(); partService.addPartToWarehouse(pId,quantity,whId); }
Со соодветен метод во сервисот :
@Transactional public void addPartToWarehouse(Integer partId, Integer quantity, Integer warehouseId) { PartIsInStockInWarehouseId tmp = new PartIsInStockInWarehouseId(partId, warehouseId); PartIsInStockInWarehouse temp = partIsInStockInWarehouseRepository.findById(tmp).get(); temp.setQuantity(temp.getQuantity() + quantity); partIsInStockInWarehouseRepository.save(temp); }