赞
踩
使用mybatis获取到SqlSession会话对象执行多条sql语句
- @Override
- public int transfer(String fromActon, String toActon, Double money) throws IOException {
-
- SqlSession sqlSession = AgentUtil.getSqlSession();
- AccountDao mapper = sqlSession.getMapper(AccountDao.class);
- Account account1 = mapper.selectByActon(fromActon);
- Account account2 = mapper.selectByActon(toActon);
- if (account1.getBalance()>money){
- account1.setBalance(account1.getBalance()-money);
- account2.setBalance(account2.getBalance()+money);
- mapper.updateByActon(account1);
- System.out.println(1/0);
- mapper.updateByActon(account2);
- sqlSession.commit();
- AgentUtil.close(sqlSession);
-
- }
- return 1;
- }
工具类获取会话对象
- public class AgentUtil {
- private static SqlSessionFactory factory;
- private AgentUtil(){}
-
- static {
- try {
- factory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- private static ThreadLocal<SqlSession> local=new ThreadLocal<>();
-
- public static SqlSession getSqlSession(){
- SqlSession sqlSession=local.get();
- if (sqlSession==null){
- sqlSession= factory.openSession();
- local.set(sqlSession);
- }
- return sqlSession;
- }
-
- public static void close(SqlSession sqlSession){
- if (sqlSession != null) {
- sqlSession.close();
- local.remove();
- }
- }
- }
解析一下这段代码:使用mybatis框架获取一个和数据库交互的SqlSession对象,在第一次创建的时候将这个对象存放到这个线程的域中,然后再业务代码中开启一个事务管理(也就是获取通过工具类获取 SqlSession sqlSession = AgentUtil.getSqlSession();) 最后执行完所有的sql操作之后一起提交到数据库。如果中途出现了异常,事务会将数据库中的操作直接回滚,避免数据出错。
在这里事务管理一共有两个作用:
1.首先会对数据库数据保护,防止异常导致数据出错
2.会将所有的数据库操作使用同一个sqlsession对象来操作
如果不启用事务管理
如果不将 sqlSession对象绑定到当前的线程域中,那么事务管理不会起作用。
一个sqlSession对象一次只能对数据库进行一次操作。那么如果不开启,第一条语句占用了当前事务(这里查询可以),第二条语句就因为获取不到这个事务导致超时异常,有一个锁在里面。
这个时候想执行你的多个语句操作,有两种解决方式:
1.将这个对象绑定到这个线程域,开启事务管理,最后一起提交
2.第二个操作就是在使用openSession(true),这样就可以关闭事务。然后使用两个SqlSession对象来操作数据库,不然会出现占用无法执行的问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。