| 95 | | Методот updateUserRating() е анотиран со `@Transactional` бидејќи содржи две поврзани операции кои мора да се извршат како една атомска единица: прво се чита тековната оценка на корисникот од базата, потоа се пресметува новата просечна оценка. Доколку овој метод не претставуваше трансакција можеше да се случи следново: два корисника истовремено да му постават оценка на ист корисник што би резултирало со загуба на една од оценките. |
| | 95 | Методот updateUserRating() е анотиран со `@Transactional` бидејќи содржи две поврзани операции кои мора да се извршат како една атомска единица: прво се чита тековната оценка на корисникот од базата, потоа се пресметува новата просечна оценка. Доколку овој метод не претставуваше трансакција можеше да се случи следново: два корисника истовремено да му постават оценка на ист корисник што би резултирало со загуба на една од оценките. |
| | 96 | |
| | 97 | === 3.Трансакција за креирање на имот |
| | 98 | {{{ |
| | 99 | @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED) |
| | 100 | public Property createPropertyWithImages(Long propertyTypeId, String name, String description, |
| | 101 | String street, String streetNumber, String municipality, |
| | 102 | String city, String country, MultipartFile[] images, |
| | 103 | UserD owner) throws IOException { |
| | 104 | try { |
| | 105 | System.out.println("=== ЗАПОЧНУВАЊЕ НА ТРАНСАКЦИЈА ЗА КРЕИРАЊЕ НА ИМОТ ==="); |
| | 106 | |
| | 107 | if (name == null || name.trim().isEmpty()) { |
| | 108 | throw new IllegalArgumentException("Property name cannot be empty"); |
| | 109 | } |
| | 110 | |
| | 111 | var propertyType = propertyTypeRepository.findById(propertyTypeId) |
| | 112 | .orElseThrow(() -> new RuntimeException("Property type not found with ID: " + propertyTypeId)); |
| | 113 | |
| | 114 | Address address = new Address(street, streetNumber, municipality, city, country); |
| | 115 | address = addressRepository.save(address); |
| | 116 | |
| | 117 | Property property = new Property(name, description, LocalDateTime.now(), owner, propertyType, address); |
| | 118 | property = propertyRepository.save(property); |
| | 119 | |
| | 120 | if (images != null && images.length > 0) { |
| | 121 | processImageUploads(images, property); |
| | 122 | } |
| | 123 | return property; |
| | 124 | |
| | 125 | } catch (Exception e) { |
| | 126 | System.err.println("ГРЕШКА ВО ТРАНСАКЦИЈА ЗА КРЕИРАЊЕ НА ИМОТ: " + e.getMessage()); |
| | 127 | throw new RuntimeException("Грешка при креирање на имот со слики: " + e.getMessage(), e); |
| | 128 | } |
| | 129 | } |
| | 130 | }}} |
| | 131 | Методот createPropertyWithImages() е анотиран со `@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)` бидејќи содржи три поврзани операции кои мора да се извршат како една атомска единица: прво се креира и зачувува адреса во базата, потоа се креира и зачувува имот кој покажува кон адресата преку address_id, и на крај се обработуваат и зачувуваат сликите во Property_Image табелата. |
| | 132 | |
| | 133 | Доколку методот не беше означен со `@Transactional` би можело да се случи успешно креирање на адреса, имот, но на пример фрлање на исклучок при процесирање на сликите, покрај тоа корисникот би помислил дека неговиот имот е креиран со слики, но всушност има имот без слики, што не е она што го барал. Трансакцијата гарантира дека или се успева (имот со слики), или ништо не се прави. |
| | 134 | |