wiki:Transactions

Version 1 (modified by 221012, 2 months ago) ( diff )

--

Трансакции

Трансакција за креирање на изнајмување

 @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public Lease save(Long listingId,
                                        Long tenantId,
                                        Long landlordUserId,
                                        LocalDate startDate,
                                        LocalDate endDate,
                                        BigDecimal rentAmount,
                                        BigDecimal depositAmount) {
        try {
            System.out.println("=== ЗАПОЧНУВАЊЕ НА ТРАНСАКЦИЈА ЗА КРЕИРАЊЕ НА ИЗНАЈМУВАЊЕ ===");
            Listing listing = listingService.findById(listingId);

            if (!"available".equals(listing.getStatus())) {
                throw new IllegalStateException("Огласот не е достапен за изнајмување. Статус: " + listing.getStatus());
            }

            TenantProfile tenant = tenantProfileService.findByUserId(tenantId);
            if (tenant == null) {
                throw new IllegalArgumentException("Изнајмувачот не е пронајден со ID: " + tenantId);
            }

            LandlordProfile landlord = landlordProfileService.findByUserId(landlordUserId);
            if (landlord == null) {
                throw new IllegalArgumentException("Издавачот не е пронајден со ID: " + landlordUserId);
            }

            System.out.println("TENANT ID: " + tenant.getId());
            System.out.println("LANDLORD ID: " + landlord.getId());

            Lease lease = new Lease(
                    startDate,
                    endDate,
                    rentAmount,
                    depositAmount,
                    listing,
                    tenant,
                    landlord
            );

            Lease savedLease = leaseRepository.save(lease);
            listing.setStatus("rented");
            listingService.save(listing);
            return savedLease;

        } catch (Exception e) {
            System.err.println("ГРЕШКА ВО ТРАНСАКЦИЈАТА: " + e.getMessage());
            throw new RuntimeException("Грешка при креирање на изнајмување: " + e.getMessage(), e);
        }
    }

Оваа трансакција вклучува повеќе операции во базата на податоци кои мора да се извршат како една целина. Методот save() е анотиран со

@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)

што значи дека сите операции во рамките на методот се третираат како една атомска единица.

Прво се проверува дали огласот постои и дали е достапен за изнајмување со статус "available". Доколку огласот не е достапен, се фрла исклучок кој автоматски ја прекинува трансакцијата и се извршува ROLLBACK.

Потоа се бараат и валидираат профилите на издавач и изнајмувачот. Доколку било кој од нив не постои во базата, повторно се фрла исклучок и трансакцијата се поништува. Со ова се постигнува CONSISTENCY- се гарантира дека во базата нема да се внесат невалидни или неконзистентни податоци. Кога сите валидации поминуваат успешно, се извршуваат две клучни операции во базата:

  • Прва операција: Се креира и зачувува изнајмување во табелата Lease
  • Втора операција: Се ажурира статусот на огласот од "available" во "rented" и истиот се зачувува во базата.

Овие две операции се атомски поврзани - или и двете ќе успеат, или и двете ќе се поништат. Не може да се случи ситуација каде изнајмувањето е креирано, а статусот на огласот не е ажуриран, или обратно.

ATOMICITY се постигнува преку @Transactional анотацијата со параметар rollbackFor = Exception.class. Ова значи дека доколку се фрли било кој исклучок при извршување на методата, сите промени што се направени до тој момент автоматски се поништуваат со ROLLBACK операцијата.

ISOLATION се постигнува преку параметарот isolation = Isolation.READ_COMMITTED кој спречува други паралелни трансакции да читаат неодобрени промени. На тој начин се гарантира дека два корисника истовремено нема да можат да креираат договор за истиот листинг.

DURABILITY се постигнува автоматски кога методот завршува успешно без фрлање на исклучок. Во тој случај, Spring автоматски врши COMMIT операција и сите промени трајно се зачувуваат во базата на податоци.

Note: See TracWiki for help on using the wiki.