ThreadLocal封装connection--隔离了相关资源,防止线程安全问题

线程安全问题的2种解决方法:
 
同步synchronized ,是一把锁,线程A操作变量X的时候,这把锁会锁住,此时其他线程B无法操作。
等线程A操作结束,锁打开,此时变量X可以被线程B操作 ----- 效果:多线程共享资源(变量)
 
另外,ThreadLocal是线程的本地变量,ThreadLocal隔离了相关资源,可以防止线程安全问题。---- 效果:一个线程对应一个ThreadLocal(独享资源),多线程不能共享资源(ThreadLocal可用于封装connection)
 

package com.qdsx.drp.util;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

 

public class ConnectionManager {

   

    //ThreadLocal

    private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>();

   

    /**

     * 得到Connection

     * @return

     */

    public static Connection getConnection(){

      

       //ThreadLocal

       Connection conn = connectionHolder.get();

      

       //ThreadLocal,如果在当前线程中没有绑定相应的Connection

       if(conn == null){

           //取得jdbc配置信息

           try {

              JdbcInfo jdbcInfo = ConfigReader.getInstance().getJdbcInfo();

              Class.forName(jdbcInfo.getDriverName()).newInstance();

              conn = DriverManager.getConnection(jdbcInfo.getUrl(), jdbcInfo.getUsername(), jdbcInfo.getPassword());

             

              //ThreadLocal,将Connection设置(set)到线程变量(connectionHolder)中

              connectionHolder.set(conn);

             

           } catch (InstantiationException e) {

              e.printStackTrace();

              throw new ApplicationException("系统错误,请联系系统管理员,qq:472989050");

           } catch (IllegalAccessException e) {

              e.printStackTrace();

              throw new ApplicationException("系统错误,请联系系统管理员,qq:472989050");

           } catch (ClassNotFoundException e) {

              e.printStackTrace();

              throw new ApplicationException("系统错误,请联系系统管理员,qq:472989050");

           } catch (SQLException e) {

              e.printStackTrace();

              throw new ApplicationException("系统错误,请联系系统管理员,qq:472989050");

           }

       }

       return conn;     

    }

   

    public static void closeConnection(){

       Connection conn = connectionHolder.get();

       if(conn != null){

           try {

              conn.close();

              //ThreadLocal中清除Connection (如果不清楚,下次拿到的还是已经closeConnection,用不了)

              connectionHolder.remove();

           } catch (SQLException e) {

              e.printStackTrace();

           }

       }

    }

   

    //以下是事务处理的封装

    public static void beginTransaction(Connection conn) {

       try {

           if(conn != null){

              if(conn.getAutoCommit()){

                  conn.setAutoCommit(false);//手动提交

              }

           }

       } catch (SQLException e) {

           e.printStackTrace();

       }

    }

   

    public static void commitTransaction(Connection conn) {

       try {

           if(conn != null){

              if(!conn.getAutoCommit()){

                  conn.commit();

              }

           }

       } catch (SQLException e) {

           e.printStackTrace();

       }

    }

   

    public static void rollbackTransaction(Connection conn) {

       try {

           if (conn != null) {

              if(!conn.getAutoCommit()){

                  conn.rollback();

              }

           }

       } catch (SQLException e) {

           e.printStackTrace();

       }

    }

   

    public static void resetConnection(Connection conn) {

       try {

           if(conn != null){

              if(conn.getAutoCommit()){

                  conn.setAutoCommit(false);

              }else{

                  conn.setAutoCommit(true);

              }

           }

       } catch (SQLException e) {

           e.printStackTrace();

       }

    }

   

    public static void setAutoCommit(Connection conn, boolean autoCommit) {

       if (conn != null) {

           try {

              conn.setAutoCommit(autoCommit);

           } catch (SQLException e) {

              e.printStackTrace();

           }

       }

    }  

}

 
在service层的使用:
 

    public void addFlowCard(FlowCard flowCard) throws ApplicationException {

       Connection conn = null;

       try {

           //取得

           conn = ConnectionManager.getConnection();

          

           //开启事务

           ConnectionManager.beginTransaction(conn);

          

           //生成流向单单号

           String flowCardVouNo = flowCardDao.generateVouNo();

           //添加流向单主信息

           flowCardDao.addFlowCardMaster(flowCardVouNo, flowCard);

           //添加流向单明细信息

           flowCardDao.addFlowCardDetail(flowCardVouNo, flowCard.getFlowCardDetailList());

      

           //提交事务

           ConnectionManager.commitTransaction(conn);

       } catch (DaoException e) {

           //异常,回滚事务

           ConnectionManager.rollbackTransaction(conn);

           e.printStackTrace();

           throw new ApplicationException("添加流向单失败!");

       }finally{

           //关闭Connection,并从ThreadLocal中清除Connection

           ConnectionManager.closeConnection();

       }     

    }

 

 

在dao层使用:

    public String generateVouNo() throws DaoException {

       Connection conn = ConnectionManager.getConnection();

       return null;

    }

 

    public void addFlowCardMaster(String flowCardVouNo, FlowCard flowCard)

           throws DaoException {

       Connection conn = ConnectionManager.getConnection();

    }

 

    public void addFlowCardDetail(String flowCardVouNo,

           List<FlowCardDetail> flowCardDetailList) throws DaoException {

       Connection conn = ConnectionManager.getConnection();

    }

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值