在基本的 MyBatis 中,session 工厂可以使用 SqlSessionFactoryBuilder 来创建。而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean 来替代。
MyBatis 的 SqlSession 提供指定的方法来处理编程式的事务。 但是当使用 MyBatis-Spring 时, bean 将会使用 Spring 管理的 SqlSession 或映射器来注入。 那就是说 Spring 通常是处理 事务的。你 不 能 在 Spring 管 理 的 SqlSession上调用 SqlSession.commit() , SqlSession.rollback() 或 SqlSession.close() 方 法 。 如果这样做了,就会抛UnsupportedOperationException 异常。注意在使用注入的映射器时不能访问那些方法。
无论 JDBC 连接是否设置为自动提交, SqlSession 数据方法的执行或在 Spring 事务之外 任意调用映射器方法都将会自动被提交。
使用编程式事务需要用PlatformTransactionManager来实现……
应用:
pom文件如下:
org.springframework.boot
spring-boot-starter
mysql
mysql-connector-java
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.1
org.springframework.boot
spring-boot-starter-web
com.github.pagehelper
pagehelper
5.0.1
org.springframework.boot
spring-boot-starter-test
test
配置SqlSessionFactoryBean
@Autowired
private DataSource dataSource;
@Bean
public SqlSessionFactory getSqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean.getObject();
}
修改application.properties文件
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/disaster?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
spring.datasource.username=root
spring.datasource.password=123456789
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
mybatis.config-location=classpath:mybatisConfig.xml
mybatisConfig.xml文件:
数据库文件:
CREATE TABLE `disaster`.`Untitled` (
`account_id` int(11) NOT NULL DEFAULT 0 COMMENT '用户主键',
`role_id` int(11) NOT NULL DEFAULT 0 COMMENT '角色主键',
PRIMARY KEY (`account_id`, `role_id`) USING BTREE,
INDEX `FKrs2s3m3039h0xt8d5yhwbuyam`(`role_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户角色表' ROW_FORMAT = Compact;
Dao层:
@Mapper
public interface TestDao {
@Insert("INSERT INTO account_role VALUES(#{id1},#{id2})")
void insert(@Param("id1")int id1,@Param("id2")int id2);
}
控制器层:
package com.example.demo;
import java.util.List;
import java.util.Map;
import javax.activation.DataSource;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/*
* @author zzf
* @date 2019年2月20日 上午9:36:30
*/
@RestController
public class TestController {
@Autowired
TestDao testDao;
@Autowired
private PlatformTransactionManager txManager;
@GetMapping("/c")
@Transactional
public void test2(){
testDao.insert(1, 100);
testDao.insert(2, 100);
testDao.insert(3, 100);
}
@GetMapping("/b")
public void test(){
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//事务状态类,通过PlatformTransactionManager的getTransaction方法根据事务定义获取;获取事务状态后,Spring根据传播行为来决定如何开启事务
TransactionStatus status = txManager.getTransaction(def);
try {
testDao.insert(1, 1);
testDao.insert(1, 2);
testDao.insert(1, 3);
txManager.commit(status);
}catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
txManager.rollback(status);
}
}
}
测试:
http://localhost:8080/b
将代码改为:
再次请求http://localhost:8080/b
说明异常回滚
测试@Transactional
http://localhost:8080/c
代码修改为:
再次运行http://localhost:8080/c
OK~说明事务生效了
推荐网站:http://www.mybatis.org/mybatis-3/zh/index.html
http://www.mybatis.org/spring/zh/index.html#
http://www.mybatis.cn/