使用Mybatis、threadLocal中Excutor was closed

关于使用Mybatis时SqlSession的报错:Excutor was closed的解决办法。(使用了threadlocal)

由于sqlsession是非线程安全的,因此在做sqlSession工具类的时候请讲SqlSession置于方法体中,不要使用与全局变量中。

以下问题基于将seatDAO放入全局变量中,导致了这个问题

public class ReserveServlet02 extends HttpServlet {

    private SeatMapper seatDAO;//全局变量
    //业务代码...
}
  • init()中不能使用try - with -resource

    public void init() {
            try (SqlSession session = DBUtil2.openSession()) {
                seatDAO = session.getMapper(SeatMapper.class);
            }
        }
    

    修改后代码

    public void init() {
            seatDAO = (SeatMapper) DBUtil2.openSession().getMapper(SeatMapper.class);
        }
    
  • 每次连接了数据库都需要重新打开,再关闭.因为我使用了一个全局的sqlSession,这个sqlSession close()之后,其他业务功能就不能再使用这个sqlSession了。除非再次把它打开。笨拙的办法就是在每个业务功能上添加这两行代码:

    	SqlSession sqlSession2 = DBUtil2.openSession();//添加事务
        seatDAO = sqlSession2.getMapper(SeatMapper.class);
    //用完之后记得关闭,不关也行,但是threadlocal就没有意义了
    

    以下是修改前的实例代码:

try {
            lock.lock();//上锁,保证线程安全

            Seat seat = seatDAO.getSeatById(seatId);
    		//没有调用DBUtil2.openSession().getMapper(),出现Excutor was closed问题
           
            if (seat != null && seat.getStatus() == 1) {
                seat.setStatus(2);

                SqlSession sqlSession2 = DBUtil2.openSession();//添加事务
                seatDAO = sqlSession2.getMapper(SeatMapper.class);
                isSuccess = seatDAO.updateSeat(seat);
                sqlSession2.commit();
                DBUtil2.close(sqlSession2);
            }
        } finally {
            lock.unlock();//记得解锁
        }
        return isSuccess;
    }

修改后的代码

try {
            lock.lock();

            SqlSession sqlSession = DBUtil2.openSession();
            seatDAO = sqlSession.getMapper(SeatMapper.class);
            Seat seat = seatDAO.getSeatById(seatId);
            DBUtil2.close(sqlSession);
    		//添加了DBUtil2.openSession().getMapper()方法后,运行正常
    
            if (seat != null && seat.getStatus() == 1) {
                seat.setStatus(2);

                SqlSession sqlSession2 = DBUtil2.openSession();//添加事务
                seatDAO = sqlSession2.getMapper(SeatMapper.class);
                isSuccess = seatDAO.updateSeat(seat);
                sqlSession2.commit();
                DBUtil2.close(sqlSession2);
            }
        } finally {
            lock.unlock();
        }
        return isSuccess;
    }

总结:修改后还是有问题,下次再解决。第一次有用,第二次之后就是有时候有用有时候没用,可能是别的部分代码有问题,也可能这种修改方式有问题,目前也不知道原理。可以尝试一下不要定义为全局变量,可能可以完美的解决问题,也是明天再试

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值