如果在任何服务中发生异常,则在Controller中进行事务回滚

时间:2014-10-26 05:33:19

标签: java spring spring-transactions

我是春天的新手,我在交易中遇到问题。

我创建了两个模型如下:

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抛出任何异常,我也想回滚它。我试图找到解决方案,但无法获得任何好的教程。任何帮助将不胜感激。

1 个答案:

答案 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();
}

解决此问题的一个选项是创建另一个服务类,其实现注入了RoleServiceUserService,标记为@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());
    }
}