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: