场景
在日常开发过程中,大家经常使用到的spring事务管理,保证更新和新增要么全部成功,要么全部失败;
但是在某些场景中,需要保证执行的sql在同一条事务中,使用mysql自带的语句可以实现;
begin;
UPDATE table SET max_id=max_id+step WHERE biz_tag=xxx;
SELECT tag, max_id, step FROM table WHERE biz_tag=xxx;
commit;
如上所述场景,需要更新完立马查询更新的内容,而此时并不能保证是否有其他人在修改当前记录,只有开启事务来保证获取到最新的数据;
实现
使用mybatis的sqlSession可以在代码中实现这种目的,话不多说上代码;
- 配置sqlSession
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Autowired
private DataSource dataSource;
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResource("classpath:/mapping/GeneratorMapper.xml"));
// 需要注意,事务依靠jdbc事务
sqlSessionFactoryBean.setTransactionFactory(new JdbcTransactionFactory());
return sqlSessionFactoryBean.getObject();
}
}
- 使用
@Test
void testTransaction(){
List<String> list = Lists.newArrayList("111", "222", "333");
// 开启事务
SqlSession sqlSession = sqlSessionFactory.openSession(false);
// 从sqlSession中获取mapper
GeneratorMapper mapper = sqlSession.getMapper(GeneratorMapper.class);
mapper.insertGenerator(list);
// 测试回滚和提交
sqlSession.rollback();
// sqlSession.commit();
}
- 最后
test中代码可以当作Service中代码来实现;