Spring事务管理

@RequestMapping(value = "/updateUser")
public void updateUser() {
	userservice.updateUser();
}
@Transactional
public void updateUser(){
    User user = userMapper.selectByPrimaryKey(1);
    user.setUserName("cdd");
    userMapper.updateById(user);
    int i = 1 / 0;
}
// 回滚
@RequestMapping(value = "/updateUser")
public void updateUser() {
	userservice.updateUser();
}
@Transactional
public void updateUser(){
    try {
        User user = userMapper.selectByPrimaryKey(1);
        user.setUserName("cdd");
        userMapper.updateById(user);
        throw new ClassNotFoundException();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}
// 不回滚

证明运行时异常会回滚,编译异常不会回滚:

spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获runtimeexception的异常,但可以通过

// service中的两个方法在同一个类中
// 第一种
@RequestMapping(value = "/updateUser")
public void updateUser() {
	userservice.updateUser();
}
public void updateUser(){
    User user = userMapper.selectByPrimaryKey(1);
    user.setUserName("cdd");
    userMapper.updateById(user);
    updateDemo();
}
@Transactional
public void updateDemo(){
    User user = userMapper.selectByPrimaryKey(2);
    user.setUserName("cdd");
    userMapper.updateById(user);
    int i = 1 / 0;
}
// 两个方法不回滚
// 第二种
@RequestMapping(value = "/updateUser")
public void updateUser() {
	userservice.updateUser();
}
@Transactional
public void updateUser(){
    User user = userMapper.selectByPrimaryKey(1);
    user.setUserName("cdd");
    userMapper.updateById(user);
    updateDemo();
}
public void updateDemo(){
    User user = userMapper.selectByPrimaryKey(2);
    user.setUserName("cdd");
    userMapper.updateById(user);
    int i = 1 / 0;
}
// 两个方法回滚
// 第三种
@RequestMapping(value = "/updateUser")
public void updateUser() {
	userservice.updateUser();
}
@Transactional
public void updateUser(){
    User user = userMapper.selectByPrimaryKey(1);
    user.setUserName("cdd");
    userMapper.updateById(user);
    updateDemo();
}
@Transactional
public void updateDemo(){
    User user = userMapper.selectByPrimaryKey(2);
    user.setUserName("cdd");
    userMapper.updateById(user);
    int i = 1 / 0;
}
// 两个方法回滚

第一种:Controller调用Service没有事务注解所以没有开启代理,方法内调用本类的有事务注解的方法,因为是同类所以调用的还是原始对象的updateDemo所以没有还是没有走Aop开启使用。

第二三种:Controller调用Service有事务注解开启代理,开启事务,方法内调用本类的方法也是在一个事务内,所以会回滚。

// 把第二个方法移到其他service中
// 第一种
@RequestMapping(value = "/updateUser")
public void updateUser() {
	userservice.updateUser();
}
@Resource
private demoservice demo;
public void updateUser(){
    User user = userMapper.selectByPrimaryKey(1);
    user.setUserName("cdd");
    userMapper.updateById(user);
    demo.updateDemo();
}
@Transactional
public void updateDemo(){
    User user = userMapper.selectByPrimaryKey(2);
    user.setUserName("cdd");
    userMapper.updateById(user);
    int i = 1 / 0;
}
// updateUser不回滚 updateDemo回滚
// 第二种
@RequestMapping(value = "/updateUser")
public void updateUser() {
	userservice.updateUser();
}
@Resource
private demoservice demo;
@Transactional
public void updateUser(){
    User user = userMapper.selectByPrimaryKey(1);
    user.setUserName("cdd");
    userMapper.updateById(user);
    demo.updateDemo();
}
@Transactional
public void updateDemo(){
    User user = userMapper.selectByPrimaryKey(2);
    user.setUserName("cdd");
    userMapper.updateById(user);
    int i = 1 / 0;
}
// updateUser回滚 updateDemo回滚

第一种:Controller调用Service没有事务注解所以没有开启代理,方法内调用另一个类的方法有事务注解开启事务。异常以后回滚,主方法没有事务所以没有回滚。

第二种:Controller调用Service有事务注解所以开启代理开启事务,方法内调用另一个类的方法有事务注解因为默认事务传播机制是PROPAGATION_REQUIRED所以所以加入事务。整体回滚。

以下是事物的传播机制:

@Transactional(propagation=Propagation.REQUIRED)
如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
@Transactional(propagation=Propagation.NOT_SUPPORTED)
容器不为这个方法开启事务
@Transactional(propagation=Propagation.REQUIRES_NEW)
不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
@Transactional(propagation=Propagation.MANDATORY)
必须在一个已有的事务中执行,否则抛出异常
@Transactional(propagation=Propagation.NEVER)
必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.SUPPORTS)
如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值