Home > Blockchain >  How Propagation REQUIRED works in spring boot?
How Propagation REQUIRED works in spring boot?

Time:09-17

I am just trying to understand the transaction propagation in spring: using jpa, postgres, validators and web starter in my project. Propogation REQUIRED says:

  • when one of these logical transactions is rolled back, all the logical transactions of the current physical transaction are rolled back.

  • but when I am throwing exception in insertUserKumar() it should not persist data in database as per documentation but its getting persisted.

  • my properties are below defined

logging.level.sql=debug
spring.datasource.generate_unique_name=false

spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=dummy
spring.datasource.password=dummy
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=update

spring.datasource.hikari.auto-commit=false
spring.jpa.properties.hibernate.connection.provider_disables_autocommit=true
  • some will say you might have missed @EnableTransactionManagement I tried it with or without that. but two records are getting persisted into database. Can anyone help me?
@Slf4j
@Component
@RequiredArgsConstructor
public class AppRunner implements CommandLineRunner {
    private final UserRepository userRepository;

    @Override
    public void run(String... args) throws Exception {
        insertUserBunty();// this transaction should fail but its getting persisted
    }

    @Transactional(propagation = Propagation.REQUIRED)
    void insertUserBunty() {
        User bunty = new User(null, "Bunty");
        userRepository.save(bunty);
        insertUserKumar();
    }

    @Transactional(propagation = Propagation.REQUIRED)
    void insertUserKumar() {
        User kumar = new User(null, "Kumar");
        userRepository.save(kumar);
        throw new RuntimeException("This will rollback both insert Bunty and Kumar");
    }
}

CodePudding user response:

The reason is that @Transactional does not work when you call the method from another method in the class. The reason being the way Spring handles the transactionality features. It is basically handled by a Proxy of your class and thus @Transactional annotation only has an effect when the method is called by a method outside your class. Check details at:

  • Related