gpt4 book ai didi

Spring Boot @Transactional 在 @Service 类(而不是 Controller )上不起作用

转载 作者:行者123 更新时间:2023-12-03 17:36:44 32 4
gpt4 key购买 nike

我认为最好的做法是放置 @Transactional服务层类上的注释,而不是 Controller 上的注释(参见 f.e. Why we shouldn't make a Spring MVC controller @Transactional? )。但这不适用于我的 Spring Boot 应用程序。这是为什么?
registerAction Controller 中的方法(见下面的代码)执行多个服务调用。当 f.e. mailService.sendActivationMail(...)失败,我想从 userService.registerUser(...) 回滚插入的用户称呼。我需要把@Transactional Controller 类上的注释与否?

@Transactional 出现时,我的 Spring Boot 应用程序正确使用事务。在 Controller 类上设置了注释:

AuthController.java

@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;
}

}

但是当 @Transactional 时事务不起作用注释设置在服务类上(而不是在 Controller 上):

UserService.java
@Service
@Transactional
public class UserService {

@Autowired
private ApiUserRepository userRepository;

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

}

我的配置类:

SpringApiApplication.java
@SpringBootApplication
public class SpringApiApplication {
public static void main(String[] args) {
SpringApplication.run(SpringApiCommonApplication.class, args);
}
}

ApiConfiguration.java
@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());
}
}

最佳答案

@M.Deinum 让我走上正轨。 Spring(引导)不会像其他框架那样自动将您的 Controller 调用包装在事务中。所以你必须添加一个 @Transactional注释到您的 Controller ,或将代码从 Controller 类移动到服务类。

将代码从 Controller 类移动到服务类是更好的做法,因为(除其他外)使代码更易于测试。所以这就是我所做的。

AuthenticationService.java

@Service
public class AuthenticationService {
@Autowired
private UserManager userManager;

@Autowired
private ProfileManager profileManager;

@Autowired
private MailManager mailManager;

@Transactional
public Profile registerUser(Registration registration) {
ApiUser user = userManager.registerUser(registration);
Profile profile = profileManager.createProfile(user, registration);

mailManager.sendActivationMail(user);

return profile;
}

...
}

AuthController.java
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationService authenticationService;

@RequestMapping(path = "register", method = RequestMethod.POST)
@ApiOperation(value = "Registers a user")
public Profile register(@Valid @RequestBody Registration registration) {
return authenticationService.registerUser(registration);
}

...
}

关于Spring Boot @Transactional 在 @Service 类(而不是 Controller )上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34614852/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com