Spring Boot @Transactional not working when on @Service class (instead of controller)
<p>I thought it was best practice to put the <code>@Transactional</code> annotation on the service layer classes and not on the controllers (see f.e. <a href="https://stackoverflow.com/questions/23118789/spring-mvc-controller-shouldnt-be-transactional-why?lq=1">Why we shouldn&#39;t make a Spring MVC controller @Transactional?</a>). But this not working on my Spring Boot application. Why is that?</p>

<p>The <code>registerAction</code> method in the controller (see code below) performs multiple service calls. When f.e. the <code>mailService.sendActivationMail(...)</code> fails, I want to rollback the inserted user from the <code>userService.registerUser(...)</code> call. Do I need to put the <code>@Transactional</code> annotation on the controller class or not?</p>

<p>My Spring Boot application correctly uses transactions when the <code>@Transactional</code> annotation is set on the controller class:</p>

<p><strong>AuthController.java</strong></p>

<pre><code>@RestController
@RequestMapping("/api/auth")
@Transactional
public class AuthController {

    @Autowired
    private UserService userService;

    @Autowired
    private ProfileService profileService;

    @Autowired
    private MailService mailService;

    @RequestMapping(path = "register", method = RequestMethod.POST)
    public Profile registerAction(@Valid @RequestBody Registration registration) {
        ApiUser user = userService.registerUser(registration);
        Profile profile = profileService.createProfile(user, registration);

        mailService.sendActivationMail(user);

        return profile;
    }

}
</code></pre>

<p>but transactions don't work when the <code>@Transactional</code> annotation is set on the Service classes instead (and not on the controller):</p>

<p><strong>UserService.java</strong></p>

<pre><code>@Service
@Transactional
public class UserService {

    @Autowired
    private ApiUserRepository userRepository;

    public ApiUser registerUser(Registration registration) {
        ...
        userRepository.save(user);
        ...
    }

}
</code></pre>

<hr>

<p>My configuration classes:</p>

<p><strong>SpringApiApplication.java</strong></p>

<pre><code>@SpringBootApplication
public class SpringApiApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringApiCommonApplication.class, args);
    }
}
</code></pre>

<p><strong>ApiConfiguration.java</strong></p>

<pre><code>@Configuration
@EnableJpaAuditing
@EnableTransactionManagement
public class ApiConfiguration {
    @Autowired
    private ApiProperties properties;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UsernameCanonicalizer usernameCanonicalizer() {
        return new UsernameCanonicalizer();
    }

    @Bean
    public EmailCanonicalizer emailCanonicalizer() {
        return new EmailCanonicalizer();
    }

    @Bean
    public ApiTokenHandler activationTokenHandler() {
        return new StandardApiTokenHandler(properties.getActivationTokenDuration());
    }
}
</code></pre>