Dilip Kumar
Dilip Kumar

Reputation: 65

Spring Service not rolling back the transaction after exception

I am using Spring JpaRepository for CRUD implementation in one of my App screens. As a part of that, I am developing a feature where user can save all Car entities or nothing (should roll back) into database. I am not sure how do I achieve this functionality using Spring Boot, Spring Rest, Spring Jpa.

Below is my source code.

@Repository
interface CarRepository extends JpaRepository<Car, Integer> { }

@Service
class CarService {

    @Autowired
    CarRepository repo;

    @Transactional(rollbackFor=RuntimeException.class)
    public List<Car> saveAllOrNone(List<Car> cars) {
        for(Car car: cars) {
            repo.save(car);
        }
    }
}

I am unable to figure out what wrong I am doing.

When I tested it using two different data among which 1 have invalid data, the other record is getting inserted into database instead of being rolled back.

In addition to this, I am getting an Exception like UOWManager transaction processing failed:nested exception is com.ibm.wsspi.uow.UOWException: javax.transaction.RollbackException

Please help me out. Thank you.

Upvotes: 2

Views: 4158

Answers (2)

Dilip Kumar
Dilip Kumar

Reputation: 65

Even though its late, I would like to post the answer because someone would find this useful. I fixed the error by implementing a JPA Transaction Manager in my spring boot application using the resource here

Upvotes: 2

Dherik
Dherik

Reputation: 19050

Seems the @Transactional is not working for you. I could understand that there is some configuration in your application that could be the responsible to not create the DataSourceTransactionManager. As explained here, this should be automatically:

Spring Boot will detect spring-jdbc on the classpath and h2 and will create a DataSource and a JdbcTemplate for you automatically. Because such infrastructure is now available and you have no dedicated configuration, a DataSourceTransactionManager will also be created for you: this is the component that intercepts the @Transactional annotated method

So I see two alternatives to resolve your problem.

The first is use the save method from Spring Repository that could accept your car list:

repo.save(cars);

This will work because the Spring has an internal @Transactional for the repository methods.

The another alternative is add together with your @SpringBootApplication the annotation @EnableTransactionManagement, enabling manually what Spring should do for you.

More details here.

Upvotes: 0

Related Questions