事务管理,AOP(1)

事务管理,AOP(1)

实现转账服务的时候,假如有异常怎么办呢?

我们先来看下面这段代码

 User source =iDao.getUserById(from);
 User target =iDao.getUserById(to);

source.setUsmoney(source.getUsmoney()-money);
target.setUsmoney(target.getUsmoney()+money);

iDao.updateUser(source);//到这里都是正常操作,source已经扣钱了
            int i = 1/0;//但是由于到
iDao.updateUser(target);

这段代码,需要完成转账的服务,但是由于异常,最后一步就不会被执行

用户来时的钱完成操作的钱
source10080
target100100

这样来源用户就会不明不白的丢失钱钱

这个时候就需要事务的管理

import com.ConnectionUtil;
import java.sql.SQLException;

/**
 * 与业务相关的工具类
 */
public class TranslationManager {
    private ConnectionUtil connectionUtil;//这个我是用sping来注入的

    public void setConnectionUtil(ConnectionUtil connectionUtil) {
        this.connectionUtil = connectionUtil;
    }

    public void beginTranslation(){
        try {
            connectionUtil.getConnection().setAutoCommit(false);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void commit(){
        try {
            connectionUtil.getConnection().commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void rollback(){
        try {
            connectionUtil.getConnection().rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void release(){
        try {
            connectionUtil.getConnection().close();
            //把当前的连接还回线程中
            connectionUtil.removeConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

创建了一个事务管理类,以及connection绑定线程的类

import javax.sql.DataSource;
import java.sql.Connection;

public class ConnectionUtil {
    //从线程中获取一个链接然后绑定
    private ThreadLocal<Connection> t1 = new ThreadLocal<Connection>();
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public Connection getConnection(){
        Connection connection = t1.get();
        //
        try{
            if(connection==null){
                //从数据库获得一个链接
                connection = dataSource.getConnection();
                t1.set(connection);
            }
        }catch (Exception e){
            throw new RuntimeException(e);
        }
        return connection;
    }
    public void removeConnection(){
        t1.remove();
    }
}

在dao层获得connection,所有dao的基类以及实现类

public class BaseDao {
    @Autowired
    ConnectionUtil connectionUtil;

    public void setConnectionUtil(ConnectionUtil connectionUtil) {
        this.connectionUtil = connectionUtil;
    }

    public Connection getConnection(){
        return connectionUtil.getConnection();
    }
}
package com;

import com.pojo.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import java.sql.SQLException;
import java.util.Arrays;

@Component(value = "com.DaoImpl")
public class DaoImpl  extends BaseDao implements IDao{
    @Autowired
    QueryRunner queryRunner;
    public static void main(String[] args) throws SQLException {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        IDao dao = context.getBean("com.DaoImpl", IDao.class);
        //dao.insertUser(new User(1,"嘻嘻嘻",100));
        //dao.updateUser(new User(1,"吃果子",120));
        System.out.println(dao.getUserById(1));

    }
    public void query(){
        try{
            Object o[] =queryRunner.query(getConnection(),"Select * from User" ,new ArrayHandler());
            System.out.println(Arrays.toString(o));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public User getUserById(int id){
        User user = null;
        try{
            user = queryRunner.query(getConnection(),"Select * from testmoney where usid = ?",new BeanHandler<User>(User.class),id);
        }catch (Exception e){
            e.printStackTrace();
        }
        return user;
    }
    public void insertUser(User user){
        try {
            queryRunner.update(getConnection(),"insert into testmoney(usname,usmoney) values (?,?)",user.getUsname(),user.getUsmoney());
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    public void updateUser(User user){
        try {
            queryRunner.update(getConnection(),"update testmoney set usname = ?, usmoney = ? where usid = ?",
                    user.getUsname(),user.getUsmoney(),user.getUsid());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


}

最后在service中进行事务管理

public class UserService implements IUserService {
    @Autowired
    IDao iDao;
    @Autowired
    TranslationManager translationManager;
    public void sendMoney(int from, int to, int money) {
        try{
            translationManager.beginTranslation();//开启事务
            User source =iDao.getUserById(from);
            User target =iDao.getUserById(to);

            source.setUsmoney(source.getUsmoney()-money);
            target.setUsmoney(target.getUsmoney()+money);
            iDao.updateUser(source);
            int i = 1/0;
            iDao.updateUser(target);

            translationManager.commit();//提交事务
        }catch (Exception e){
            translationManager.rollback();//回滚处理异常
            throw new RuntimeException(e);
        }finally {
            translationManager.release();//释放连接
        }

    }
}

在这里插入图片描述

总的结构流程图。

可是这样太麻烦了,spring提供了一套aop的方法,让我们解决这种切面的问题,我们下一章再说。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值