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 | |