随笔都是学习笔记
随笔仅供参考,为避免笔记中可能出现的错误误导他人,请勿转载。

@Transactional:

可以标记在类、方法,标记后整个范围都会启动事务(优先执行方法上的事务启动)。

建议:@Transeactional写在方法上面,控制粒度更细,建议@Transactional写在业务逻辑层上,因为只有业务逻辑层才会有Dao层不同操作类的嵌套调用的情况。

一、注入事务管理器:

 

二、注册事务驱动:

三、在Dao中有类:

package cn.cdulm.dao.impl;

import cn.cdulm.dao.IUserDao;
import cn.cdulm.entity.User;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class UserDaoImpl implements IUserDao {
    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void setDataSource(DruidDataSource dataSource){
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
    @Override
    public User getUser(){
        return jdbcTemplate.queryForObject("select * from account where id=1", new BeanPropertyRowMapper<>(User.class));
    }

    /**
     * id=1扣钱
     */
    @Override
    public void sub() {
        jdbcTemplate.update("update account set balance=balance-100 where id=1");
    }

    /**
     * id=3加钱
     */
    @Override
    public void save() {
        jdbcTemplate.update("update account set balance=balance-100 where id=3");
    }
}

 

四、有服务类:

package cn.cdulm.service.impl;

import cn.cdulm.dao.IUserDao;
import cn.cdulm.entity.User;
import cn.cdulm.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    IUserDao userDao;

    /**
     * 转账
     */
    @Transactional  // 开启事务
    public void trans(){
        sub();  // id=1扣钱
        int i =1/0; // 此时会报错,如果不启动事务那么只会执行前面的代码而不会执行后面的代码
        save(); // id=3加钱
    }

    /**
     * 扣钱
     */
    public void sub(){
        System.out.println("扣钱");
        userDao.sub();

    }

    /**
     * 存钱
     */
    public void save(){
        System.out.println("加钱");
        userDao.save();
    }

    @Override
    public User getUser(){
        return userDao.getUser();
    }
}

 

五、测试方法:

 

 

转账之前:

 

 注意转账方法里面有个异常:

 

 先关闭事务打开异常后执行测试方法:

 

 

 

 id=1的钱减少一百,但是id=3的钱并没有增加,这说明save()存钱方法没有执行。

现在开启事务(取消@Transactional 的注释):

再次执行测试方法:

 

 同样会报错,但是:

 

 数据库中的余额并没有改变,说明事务生效进行了回滚操作。

 

posted on 2022-06-02 22:36  时间完全不够用啊  阅读(238)  评论(0编辑  收藏  举报