Mybatis 的事务控制
面试常问
- 事务是什么
- 事务的四大特性ACID
- 不考虑隔离性会产生的3个问题
- 解决方法:四种隔离级别
通过sqlsession对象的commit方法和rollback方法实习事务提交和回滚
Mybatis 框架因为是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC 的 setAutoCommit()方法来设置事务提交方式的。来跟踪源码验证这个事实
1跟踪源码
1.1org/apache/ibatis/session/SqlSession.java
1.2org/apache/ibatis/session/defaults/DefaultSqlSession.java
1.3org/apache/ibatis/executor/Executor.java
1.4通过UML Diagram追踪到BaseExecutor
1.5 org/apache/ibatis/executor/BaseExecutor.java
1.6org/apache/ibatis/transaction/Transaction.java
1.7找到实现类JdbcTransaction
1.8org/apache/ibatis/transaction/jdbc/JdbcTransaction.java
protected void setDesiredAutoCommit(boolean desiredAutoCommit) {
。。。。
log.debug("Setting autocommit to " + desiredAutoCommit + " on JDBC Connection [" + connection + "]");
。。。。。
}
2.自动提交事务
为什么 CUD 过程中必须使用 sqlSession.commit()提交事务?
主要原因就是在连接池中取出的连接,都会将调用 connection.setAutoCommit(false)方法,这样我们就必须使用 sqlSession.commit()方法,相当于使用了 JDBC 中的 connection.commit()方法实现事务提 交。
SqlSessionFactory
public interface SqlSessionFactory {
SqlSession openSession();
SqlSession openSession(boolean autoCommit);
SqlSession openSession(Connection connection);
SqlSession openSession(TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType);
SqlSession openSession(ExecutorType execType, boolean autoCommit);
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType, Connection connection);
Configuration getConfiguration();
}
修改@before中的openSession方法的true,默认是flase,就不用在@after中加入sqlSession.commit()
@Before//用于在测试方法执行之前执行
public void init() throws IOException {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapperConfig.xml");
//2.创建SqlSessionFactory工厂对象,获得数据源配置信息
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.工厂对象根据信息创建SqlSession对象
sqlSession = factory.openSession(true);
//4.使用SqlSession创建Dao接口的动态代理对象
userDao = sqlSession.getMapper(UserDao.class);
}
@After //用于在测试方法执行之后执行
public void destroy()throws Exception{
//提交事务,如果不提交,会回滚操作,表数据直接跳一行
// sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
测试保存autocommit,不适用实际一个方法中多个需要事务控制sql,在Spring中会用AOP解决