brak rollbacku

0

Dlaczego to mi nie rollbackuje xD . Uprościłem tę metodę maksymalnie tylko po to żeby zobaczyć czy kiedy mi wyrzuci runtime exception(po dodaniu drugiej wizyty o tym samym czasie) to wywala błąd ale mimo to nie cofa z bazy danych i mam exception "Visits with such date already with database" i status 500 a mimo to w bazie danych zostaje ta krotka

@EnableTransactionManagement
@Transcational
@Service
            public class VisitService {

                private final static Logger logger = LoggerFactory.getLogger(VisitService.class);

                private final VisitRepository visitRepository;

                public VisitService(VisitRepository visitRepository) {
                    this.visitRepository = visitRepository;
                }

                public List<Visit> findAllByDate(LocalDateTime date){

                    return  visitRepository.findAllByDate(date);
                }

                @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = RuntimeException.class, propagation = Propagation.REQUIRED)
                public Visit save(@Valid Visit visit) {
                    logger.info("Inside visitService");
                    visit.setPayed(false);
                    if (visit.getPrice().intValue() > 1000)
                        visit.setDiscount(new BigDecimal(0.05));
                    else visit.setDiscount(new BigDecimal(0.00));

                    visitRepository.save(visit);
                    if(findAllByDate(visit.getDate()).size()>1)
                        throw new RuntimeException();

                    return  null;

                }

            }

istotna cześć stack trace'a

2018-12-08 23:16:23.653 TRACE 3360 --- [nio-8080-exec-2] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
Hibernate: insert into visits (visit_date, description, discount, payed, pet_id, price, vetid) values (?, ?, ?, ?, ?, ?, ?)
2018-12-08 23:16:23.663 TRACE 3360 --- [nio-8080-exec-2] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2018-12-08 23:16:23.664 TRACE 3360 --- [nio-8080-exec-2] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAllByDate]
Hibernate: select visit0
.id as id16, visit0_.visit_date as visit_da26, visit0_.description as descript36, visit0_.discount as discount46, visit0_.payed as payed56, visit0_.pet_id as pet_id66, visit0_.price as price76, visit0_.vet_id as vet_id86 from visits visit0 where visit0.visit_date=?
2018-12-08 23:16:23.685 TRACE 3360 --- [nio-8080-exec-2] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAllByDate]
2018-12-08 23:16:23.685 TRACE 3360 --- [nio-8080-exec-2] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.samples.petclinic.services.VisitService.save] after exception: java.lang.RuntimeException
2018-12-08 23:16:23.685 TRACE 3360 --- [nio-8080-exec-2] o.s.t.i.RuleBasedTransactionAttribute : Applying rules to determine whether transaction should rollback on java.lang.RuntimeException
2018-12-08 23:16:23.685 TRACE 3360 --- [nio-8080-exec-2] o.s.t.i.RuleBasedTransactionAttribute : Winning rollback rule is: RollbackRuleAttribute with pattern [java.lang.RuntimeException]
2018-12-08 23:16:23.690 DEBUG 3360 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Failed to complete request: java.lang.RuntimeException
2018-12-08 23:16:23.698 ERROR 3360 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException] with root cause

java.lang.RuntimeException: null

0

DataSource z autocomitem ?

1

Pewnie masz transakcję na każdym save którą jest od razu commitowana. Czy używasz JpaRepository? jeżeli tak to by się zgadzało.
Pokaż kod VisitRepository.

Edit: po logach widzę że to JpaRepository
Możesz spróbować dać enableDefaultTransactions = false w @EnableJpaRepositories. To wyłączy transakcje na metodach JpaRepository i pozwoli samemu ustawiać @Transactional tam gdzie się chce. Trzeba pamiętać że to ustawienie globalne.

0

Znowu komuś magia nie działa. Dziwne, nie?

Transakcja w JPARepository nie ma znaczenia, bo przecież ta zewnętrzna (VisitService.save) jest propagowana( a raczej powinna być).
(btw. te wszystkie parametry (isolation = Isolation.READ_COMMITTED, rollbackFor = RuntimeException.class, propagation = Propagation.REQUIRED) możesz sobie odpuścić).
Dlaczego nie jest?
Nie widzę błędu w tym kawałku kodu, pokaż jak wywołujesz VisitService.save, tam chyba jest jakiś kanał.
I w ogóle dziwne jest to @EnableTransactionManagement... korzystasz ze springboot ? Bo jeśli nie to ta adnotacja jest w złym miejscu (co może powodować twój problem). Jeśli korzystasz ze springboot ... to jest niepotrzebna.

0
Seti87 napisał(a):

Pewnie masz transakcję na każdym save którą jest od razu commitowana. Czy używasz JpaRepository? jeżeli tak to by się zgadzało.
Pokaż kod VisitRepository.

Edit: po logach widzę że to JpaRepository
Możesz spróbować dać enableDefaultTransactions = false w @EnableJpaRepositories. To wyłączy transakcje na metodach JpaRepository i pozwoli samemu ustawiać @Transactional tam gdzie się chce. Trzeba pamiętać że to ustawienie globalne.


public interface VisitRepository extends Repository<Visit, Integer> {

    Visit save(Visit visit);

    List<Visit> findByPetId(Integer petId);

    Visit findById(Integer visitId);

    @Transactional(readOnly = true)
    List<Visit> findAllByDate(LocalDateTime date);

    Visit findByDate(LocalDateTime date);

}
0

Ale po co transactional w Repository to ja nie wiem

0
scibi92 napisał(a):

Ale po co transactional w Repository to ja nie wiem

Tzn tam było dziwne zachowanie. Za pewne to dlatego że czegoś nie rozumiem ale w momencie kiedy robiłem findAll to w bazie danych pojawiała się dana, więc dla pewności dodałem flage że to do odczytu ale to i tak nic nie dało i za każdym razem kiedy robiłem findAll to wtedy właśnie przed save pojawiała już w bazie danych ;/

0

Nie możesz pokazać całości kodu? Jak dla mnie za dużo coś kombinujesz...

0
scibi92 napisał(a):

Nie możesz pokazać całości kodu? Jak dla mnie za dużo coś kombinujesz...

https://github.com/CharlesCZ/problem

0

@masterkwi: Ty ten serwis wywołujesz tylko z poziomu VisitControllera? W takim razie wywal wszystkie transactionale z niekontrolerów i daj znać :D

poza tym to @EnableJpaTransactional (czy jakoś tak) powinno być w klasie z adnotacja @Configuration

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0