事务与批量写入

笔记/Java/Java 持久层/MyBatis/事务与批量写入

前置:动态 SQL

TransactionDemo.java#

package demo.mybatis;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
public class TransactionDemo {
public static void main(String[] args) throws Exception {
try (InputStream in = Resources.getResourceAsStream("mybatis-config.xml")) {
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
try (SqlSession session = factory.openSession(false)) {
UserMapper mapper = session.getMapper(UserMapper.class);
User alice = mapper.selectById(findIdByName(mapper, "alice"));
mapper.updateEmail(alice.getId(), "alice.mybatis@example.com");
session.commit();
System.out.println("commit ok: alice updated");
}
try (SqlSession session = factory.openSession(false)) {
UserMapper mapper = session.getMapper(UserMapper.class);
User bob = mapper.selectById(findIdByName(mapper, "bob"));
mapper.updateEmail(bob.getId(), "bob.fail@example.com");
throw new IllegalStateException("simulate error");
} catch (Exception ex) {
System.out.println("rollback expected: " + ex.getMessage());
}
try (SqlSession session = factory.openSession(true)) {
UserMapper mapper = session.getMapper(UserMapper.class);
User bob = mapper.selectById(findIdByName(mapper, "bob"));
System.out.println("bob email still: " + bob.getEmail());
}
}
}
private static long findIdByName(UserMapper mapper, String name) {
return mapper.search(name, 1).stream()
.filter(u -> name.equals(u.getUserName()))
.findFirst()
.map(User::getId)
.orElseThrow();
}
}

openSession(false) = 手动提交;异常时 SqlSession 关闭会 rollback 未提交变更。

BatchDemo.javaExecutorType.BATCH#

package demo.mybatis;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
public class BatchDemo {
public static void main(String[] args) throws Exception {
try (InputStream in = Resources.getResourceAsStream("mybatis-config.xml")) {
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
try (SqlSession session = factory.openSession(ExecutorType.BATCH, false)) {
UserMapper mapper = session.getMapper(UserMapper.class);
for (int i = 0; i < 5; i++) {
mapper.insert(new User("batch" + i, "b" + i + "@example.com", 1));
}
session.flushStatements();
session.commit();
System.out.println("batch insert committed");
}
}
}
}

运行#

Terminal window
mvn -q exec:java -Dexec.mainClass=demo.mybatis.TransactionDemo
mvn -q exec:java -Dexec.mainClass=demo.mybatis.BatchDemo

一级缓存(同 Session)#

同一 SqlSession 内重复 selectById 可能命中一级缓存;update/insert/delete 会清空缓存。生产多实例部署时二级缓存慎用,更常配合 Redis。

对比 JDBC 事务 Demo · 增强开发见 MyBatis-Plus

文章目录

文章目录