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);
}