Spring中的事务
使用 MyBatis-Spring 允许 MyBatis 参与到 Spring 的事务管理中。而不是给 MyBatis 创建一个新的专用事务管理器。
分类
- 标准配置(利用AOP进行切面配置)
- 编程式配置事务(旧方法)
标准配置
开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象。
<!-- 配置声明式事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
接着配置事务通知,事务通知的子标签内容为给某方法添加某属性。
属性有是否只读,事务的传播特性(REQUIRED为添加一个新事务,默认)等等。
<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给哪些方法配置事务-->
<!--配置事务的传播特性:-->
<tx:attributes>
<!-- <tx:method name="add" propagation="REQUIRED"/>-->
<!-- <tx:method name="delete" propagation="REQUIRED"/>-->
<!-- <tx:method name="update" propagation="REQUIRED"/>-->
<!-- <tx:method name="query" read-only="true"/>-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
最后配置事务的切入
<!--配置事务的切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.qf.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
简单测试,先插入后删除,其中删除sql有误,若事务失败,则插入成功但删除失败;若事务成功,则插入也失败。
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> selectUsers() {
User user = new User(7, "阿拉蕾", 1);
UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
mapper.addUser(user);
mapper.deleteUser(7);//其中sql语句有误
return mapper.selectUsers();
}
}
其中delete语句故意写错,对应sql语句为,
<select id="selectUsers" resultType="user">
select * from mp.tbl_user;
</select>
<insert id="addUser" parameterType="user">
insert into mp.tbl_user(id,name,logic_flag) values(#{id},#{name},#{logic_flag});
</insert>
<delete id="deleteUser" parameterType="int">
deletes from mp.tbl_user where id=#{id}
</delete>
测试代码
public class MyTest {
@Test
public void test() throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
for (User user : userMapper.selectUsers()) {
System.out.println(user);
}
}
}
原表:
测试后,报错。
数据没有插入成功,事务配置生效。
编程式事务
当使用 MyBatis-Spring 时,你的 bean 将会注入由 Spring 管理的 SqlSession 或映射器。也就是说,Spring 总是为你处理了事务。
你不能在 Spring 管理的 SqlSession 上调用 SqlSession.commit(),SqlSession.rollback() 或 SqlSession.close() 方法。如果这样做了,就会抛出 UnsupportedOperationException 异常。在使用注入的映射器时,这些方法也不会暴露出来。
- 如果想使用编程式事务,可以使用PlatformTransactionManager 手工管理事务。
public class UserService {
private final PlatformTransactionManager transactionManager;
public UserService(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void createUser() {
TransactionStatus txStatus =
transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
userMapper.insertUser(user);
} catch (Exception e) {
transactionManager.rollback(txStatus);
throw e;
}
transactionManager.commit(txStatus);
}
}
- 在使用 TransactionTemplate 的时候,可以省略对 commit 和 rollback 方法的调用。
public class UserService {
private final PlatformTransactionManager transactionManager;
public UserService(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void createUser() {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(txStatus -> {
userMapper.insertUser(user);
return null;
});
}
}