读mybatis源码之十四:mybatis事务处理

来源:互联网 发布:daxulu域名更换 编辑:程序博客网 时间:2024/05/02 04:25

1、自身事务处理

public void doxxxxx(){ TransactionFactory transactionFactory = new JdbcTransactionFactory(); userMapper userDao=getSession().getMapper(UserMapper.class); Transaction newTransaction=transactionFactory.newTransaction(getSession().getConnection()); try {  userDao.insert(xxx);  userDao.update(xxx); } catch (Exception e) {  newTransaction.rollback();  e.printStackTrace(); } finally {    newTransaction.close(); }}
可以看出主要是事务连接。

2、与spring集成后,事务处理

BlogMapper mapper = (BlogMapper)app.getBean("blogMapper");    Blog sblog = new Blog();    sblog.setId(2);    sblog.setName("测试加密555");    sblog.setAddr("测试加密--------------123444");    mapper.insertBlogByObj(sblog);
这种数据能够提交上去,为什么呢? 看看与spring集成后它的处理方式
首先看如何得到mapper的,通过MapperFactoryBean的getObject()    方法得到
  public T getObject() throws Exception {    return getSqlSession().getMapper(this.mapperInterface);  }
那getSqlSession()又是如何得到的呢?跟踪是通过SqlSessionTemplate得到,SqlSessionTemplate里面是什么呢?
发现是一个sqlSessionProxy代理:
 public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,      PersistenceExceptionTranslator exceptionTranslator) {    notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");    notNull(executorType, "Property 'executorType' is required");    this.sqlSessionFactory = sqlSessionFactory;    this.executorType = executorType;    this.exceptionTranslator = exceptionTranslator;    this.sqlSessionProxy = (SqlSession) newProxyInstance(        SqlSessionFactory.class.getClassLoader(),        new Class[] { SqlSession.class },        new SqlSessionInterceptor());  }
具体看SqlSessionInterceptor,就可以看出为什么spring集成后,不显示提交,也能自动提交了:
  private class SqlSessionInterceptor implements InvocationHandler {    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {      final SqlSession sqlSession = getSqlSession(          SqlSessionTemplate.this.sqlSessionFactory,          SqlSessionTemplate.this.executorType,          SqlSessionTemplate.this.exceptionTranslator);      try {        Object result = method.invoke(sqlSession, args);        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {          // force commit even on non-dirty sessions because some databases require          // a commit/rollback before calling close()          sqlSession.commit(true);        }        return result;      } catch (Throwable t) {        Throwable unwrapped = unwrapThrowable(t);        if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {          Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);          if (translated != null) {            unwrapped = translated;          }        }        throw unwrapped;      } finally {        closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);      }    }  }

  if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
          // force commit even on non-dirty sessions because some databases require
          // a commit/rollback before calling close()
          sqlSession.commit(true);
        }
这部分重点,如果配置了事务,就由配置事务处理,没有配置就直接提交,所以这里相当于他帮你提交了。
closeSqlSession里面也是一样,如果有事务,是session释放,如果没有就是session关闭,跟踪下去就是事务关闭,mybatis  spring结合后里面SpringManagedTransaction的close,用的DataSourceUtils的releaseConnection
  public void close() throws SQLException {
    releaseConnection(this.connection, this.dataSource);
  }






0 0
原创粉丝点击