MyBatis事务

MyBatis框架的事务控制方式

Mybatis 框架因为是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC 的setAutoCommit()方法来设置事务提交方式的。

  1. setAutoCommit(false)情况下表示没有开启自动提交事务,需要利用sqlSession.commit()手动提交事务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class MyBatisTest {
private InputStream in;
private SqlSession session;
private UserDao mapper;

@Before //用户在测试方法之前执行
public void init() throws IOException {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);//这是一个接口,不能直接new
//3.使用工厂生产SqlSession对象
session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
mapper = session.getMapper(UserDao.class);
}

@After //用于在测试之后执行
public void destroy() throws IOException {
//提交事务
session.commit();
in.close();
session.close();
}
/*测试聚合函数count*/
@Test
public void test6(){
int total = mapper.findTotal();
System.out.println(total);
}
}

Mybatis 自动提交事务的设置

CUD(增删改) 过程中必须使用 sqlSession.commit()提交事务。主要原因就是在连接池中取出的连接,都会将调用 connection.setAutoCommit(false)方法。这样我们就必须使用 sqlSession.commit()方法,相当于使用了 JDBC 中的 connection.commit()方法实现事务提交。最后底层是调用的JdbcTransaction类中实现的commit和roolback方法。

如果是查询操作,在sqlSession.commit()的底层是不会执行connection.commit操作的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void commit() throws SQLException {
if (this.connection != null && !this.connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Committing JDBC Connection [" + this.connection + "]");
}

this.connection.commit();
}

}

public void rollback() throws SQLException {
if (this.connection != null && !this.connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Rolling back JDBC Connection [" + this.connection + "]");
}

this.connection.rollback();
}

}

我们可以在factory.openSession(true);传入true,则开启了自动提交。观察DefaultSqlSessionFactory类中的openSession方法,可以传入true或者false选择关闭/开启自动提交事务

1
2
3
public SqlSession openSession(boolean autoCommit) {
return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, autoCommit);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Before  //用户在测试方法之前执行
public void init() throws IOException {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);//这是一个接口,不能直接new
//3.使用工厂生产SqlSession对象
session = factory.openSession(true);
//4.使用SqlSession创建Dao接口的代理对象
mapper = session.getMapper(UserDao.class);
}

@After //用于在测试之后执行
public void destroy() throws IOException {
in.close();
session.close();
}