• ThreadLocal 开启事务


    1、ThreadLocal该类提供了线程局部变量
    2、分析原理:
    ThreadLocal内部有一个Map。Map的key是当前线程对象,value是一个Object对象。
    模拟该类:
    public class ThreadLocal<T>{
    private Map<Runnable,T> map = new HashMap<Runnable,T>();
    
    public void set(T t){
    map.put(Thread.currentThread(),t);
    //把传入的参数绑定到当前线程上
    }
    public void remove(){
    map.remove(Thread.currentThread());
    //从当前线程上删除对象
    }
    public T get(){
    return map.get(Thread.currentThread());
    //获取当前线程上绑定的对象
    }
    }


    dao层

    package
    com.itheima.dao.impl; import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import com.itheima.dao.AccountDao; import com.itheima.domain.Account; import com.itheima.utils.TransactionManager; /** * */ public class AccountDaoImpl implements AccountDao { private QueryRunner qr = new QueryRunner(); @Override public Account getAccountByName(String accountName) { try { Account acc = qr.query(TransactionManager.getConnection(),"select * from account where name=?", new BeanHandler<Account>(Account.class),accountName); return acc; } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } @Override public void updateAccount(Account acc) { try { qr.update(TransactionManager.getConnection(),"update account set money=? where name=?", acc.getMoney(),acc.getName()); } catch (SQLException e) { e.printStackTrace(); } } }

    service层

    package com.itheima.service.impl;
    
    import com.itheima.dao.AccountDao;
    import com.itheima.dao.impl.AccountDaoImpl;
    import com.itheima.domain.Account;
    import com.itheima.service.AccountService;
    import com.itheima.utils.TransactionManager;
    /**
    AOP:Aspect Object Program   (面向切面编程   面向方面编程)
            名词介绍:
                    就是将事物的某个方面功能代码抽取出去集中做实现,在需要系统需要用的时候,就将方面代码织入(加入)到系统中,从而实现功能扩展
            它打破了原有纵向继承体系结构(代码复用),可以在关键时候横向织入方面代码(代码复用)
            
            实现原理:
                  动态代理模式
                  
            适合场景:事务控制  ,日志控制,权限管理,积分功能
     * @author wangli
     *
     */
    public class AccountServiceImpl implements AccountService {
    
    
        @Override
        public void transfor(String sourceAcc, String targetAcc, float money) {
        
                     AccountDao dao = new AccountDaoImpl();
                    //1.根据源账户名,得到一个账户对象
                    Account srcAcc = dao.getAccountByName(sourceAcc);//非常关键,目的是确保dao中用的是同一个Connection对象
                    //2.目标对象名,得到一 个目标账户
                    Account tarAcc = dao.getAccountByName(targetAcc);
                    //3.更新余额
                    srcAcc.setMoney(srcAcc.getMoney()-money);//源账户减
                    tarAcc.setMoney(tarAcc.getMoney()+money);//目标账户加
                    
                    //4.写入到表中
                    dao.updateAccount(srcAcc);
                    int i=1/0;
                    
                    dao.updateAccount(tarAcc);
                    
            
    
            }
            
    
    }

    threadlocal 

    package com.itheima.utils;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    
    /**
     * 处理事务 的专门类   
     *                 也就是将这个事务处理的方面分离出来,形成一个独立的类
     * 
     * 就是后面要说的方面代码
     * @author wangli
     *
     */
    public class TransactionManager {
    
        private static ThreadLocal<Connection> tL = new ThreadLocal<Connection>();//线程局部变量,用于放入Connection
        /**
         * 得到连接
         * @return
         */
        public static Connection getConnection(){
            Connection con = tL.get();//从线程局部变量取出一个Connection   ----第一次没有值
            if(con==null){
                //-第一次没有值
                con = C3P0Util.getConneciton();//从连接池中取出一个连接
                tL.set(con);//放入一个连接到线程局部变量中
            }
            return con;
        }
        
        
        /**
         * 开启事务
         * @throws Exception 
         */
        public static void startTransaction() throws Exception{
            Connection con = getConnection();
            con.setAutoCommit(false);
        }
        
        /**
         * 提交事务
         * @throws Exception 
         */
        public static void commit() throws Exception{
            Connection con = getConnection();
            con.commit();
        }
        
        /**
         * 回滚事务 
         * @throws Exception 
         */
        public static void rollback() throws Exception{
            Connection con = getConnection();
            con.rollback();
        }
    }
  • 相关阅读:
    文件拖放
    有关函数传参的结构赋值的理解
    js_点击弹出图片
    js 比较网址与a链接
    css——鼠标经过按钮时样式(radial-gradient)
    文字跳动
    kafka 数据存储和发送
    kafka 消息存储分析
    Kafka 内存管理类BufferPool
    聊聊kafka-client的源码
  • 原文地址:https://www.cnblogs.com/baijin05/p/5075961.html
Copyright © 2020-2023  润新知