spring事务

public interface IUserService {
    void update();
}

@Service
public class UserService implements IUserService {
    @Autowired
    UserMapper userMapper;

    @Autowired
    RoleMapper roleMapper;

    @Transactional
    public void update() {
        User user = new User();
        user.setUserId(1);
        user.setUsername("jack1");
        // 更新user表
        userMapper.updateByPrimaryKeySelective(user);
        Role role = new Role();
        role.setRoleId(1);
        role.setRoleName("董事长1");
        int i = 1/0;
        // 更新role表
        roleMapper.updateByPrimaryKeySelective(role);
    }
}

在没有使用@Transactional注解的时候,user被更新成功,role没有更新,在使用了注解后,两个都没有更新成功。

@Transactional
public void update() {
    User user = new User();
    user.setUserId(1);
    user.setUsername("jack1");
    userMapper.updateByPrimaryKeySelective(user);
    Role role = new Role();
    role.setRoleId(1);
    role.setRoleName("董事长1");
    try {
        int i = 1/0;
    } catch (Exception e) {
        e.printStackTrace();
    }
    roleMapper.updateByPrimaryKeySelective(role);
}

在产生运行时异常的代码处使用try-catch后,两者都更新成功,事务不会回滚。该情况同样使用于受检查异常(FileInputStream fileInputStream = new FileInputStream("1.txt");

@Transactional
public void update() throws FileNotFoundException {
    User user = new User();
    user.setUserId(1);
    user.setUsername("jack1");
    userMapper.updateByPrimaryKeySelective(user);
    Role role = new Role();
    role.setRoleId(1);
    role.setRoleName("董事长1");
    FileInputStream fileInputStream = new FileInputStream("1.txt");
    roleMapper.updateByPrimaryKeySelective(role);
}

对于受检查异常,如果用throws抛出,此时事务得不到控制,异常前面的更新被执行,后面的不会执行。

@Transactional(rollbackFor = FileNotFoundException.class)
public void update() throws FileNotFoundException {
    User user = new User();
    user.setUserId(1);
    user.setUsername("jack1");
    userMapper.updateByPrimaryKeySelective(user);
    Role role = new Role();
    role.setRoleId(1);
    role.setRoleName("董事长1");
    FileInputStream fileInputStream = new FileInputStream("1.txt");
    roleMapper.updateByPrimaryKeySelective(role);
}

使用rollbackFor指定回滚的异常后,事务得到控制。

public class MyException extends RuntimeException {

    public MyException(String s) {
        super();
    }
}

@Transactional
public void update() {
    User user = new User();
    user.setUserId(1);
    user.setUsername("jack1");
    userMapper.updateByPrimaryKeySelective(user);
    Role role = new Role();
    role.setRoleId(1);
    role.setRoleName("董事长1");
    int i = 0;
    if (i == 0) {
        throw new MyException("自定义异常");
    }
    roleMapper.updateByPrimaryKeySelective(role);
}

如果中间可能会抛出自定义异常,是可以不用在rollbackFor中指定回滚的异常类型为自定义的异常类型,上面例子中事务得到控制,即都更新失败。

@Service
public class UserService implements IUserService {
    @Autowired
    UserMapper userMapper;

    @Autowired
    RoleMapper roleMapper;

    public void testUpdate() {
        update();
    }

    @Transactional
    public void update() {
        User user = new User();
        user.setUserId(1);
        user.setUsername("jack1");
        userMapper.updateByPrimaryKeySelective(user);
        Role role = new Role();
        role.setRoleId(1);
        role.setRoleName("董事长1");
        int i = 1/0;
        roleMapper.updateByPrimaryKeySelective(role);
    }
}

在一个没有加注解的方法中,调用加了事务注解的方法,事务得不到控制,原因是在test方法中调用update方法,不是使用的代理对象执行update方法的。解决办法就是给test方法也加上事务,或者在test方法中显示的使用代理对象,代码如下

@Service
public class UserService implements IUserService {
    @Autowired
    UserMapper userMapper;

    @Autowired
    RoleMapper roleMapper;
    
	//@Transactional
    public void testUpdate() {
        UserService service = (UserService) AopContext.currentProxy();
        service.update();
    }

    @Transactional
    public void update() {
        User user = new User();
        user.setUserId(1);
        user.setUsername("jack1");
        userMapper.updateByPrimaryKeySelective(user);
        Role role = new Role();
        role.setRoleId(1);
        role.setRoleName("董事长1");
        int i = 1/0;
        roleMapper.updateByPrimaryKeySelective(role);
    }
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值