我是春天的新手,我在交易中遇到问题。
我创建了两个模型如下:
UserDto - Stored user information
RoleDto - Stored user's role information
两个模型的服务如下(均使用@Transactional注释):
UserService - void saveUser(UserDto userDto) throws Exception;
RoleService - void saveRole(RoleDto roleDto) throws Exception;
现在当用户在应用程序中创建帐户时,我调用了控制器的“添加”方法,其中包含如下代码片段:
userService.saveUser(userDto);
roleService.saveRole(roleDto);
现在在此代码中,如果Roleservice中发生异常,则仍将用户数据插入数据库表。但是如果roleService抛出任何异常,我也想回滚它。我试图找到解决方案,但无法获得任何好的教程。任何帮助将不胜感激。
答案 0 :(得分:3)
您调用方法的方式使每个方法都有自己的事务。您的代码可以理解为:
Transaction t1 = Spring.createTransaction();
t1.begin();
try {
//your first service method marked as @Transactional
userService.saveUser(userDto);
t1.commit();
} catch (Throwable t) {
t1.rollback();
} finally {
t1.close();
}
Transaction t2 = Spring.createTransaction();
t2.begin();
try {
//your second service method marked as @Transactional
roleService.saveRole(roleDto);
t2.commit();
} catch (Throwable t) {
t2.rollback();
} finally {
t2.close();
}
解决此问题的一个选项是创建另一个服务类,其实现注入了RoleService
和UserService
,标记为@Transactional
并调用这两种方法。这样,两种方法都将共享此类中使用的相同事务:
public interface UserRoleService {
void saveUser(UserDto userDto, RoleDto roleDto);
}
@Service
@Transactional
public class UserRoleServiceImpl implements UserRoleService {
@Autowired
UserService userService;
@Autowired
RoleService roleService;
@Override
public void saveUser(UserDto userDto, RoleDto roleDto) {
userService.saveUser(userDto);
roleService.saveRole(roleDto);
}
}
更好的设计是将RoleDto
设为USerDto
字段,USerService
的实现会注入RoleService
字段并执行必要的调用以保存每个字段。请注意,服务类必须提供包含业务逻辑的方法,这也意味着业务逻辑规则。服务类不仅仅是Dao类的包装器。
这可能是上述解释的实现:
@Service
public class UserServiceImpl implements UserService {
@Autowired
RoleService roleService;
public void saveUSer(UserDto userDto) {
//code to save your userDto...
roleService.saveRole(userDto.getRoleDto());
}
}