redis事务
- redis最好的事务方式还是用它自己的watch 读数据,然后再用multi进行锁定,最后用exec执行,如果成功返回[null,true],如果失败返回操作结果[结果,false]
- redis的事务很容易与mysql数据库的事务混在一起,尽量不要打开。默认redis的事务是关闭的。非要打开的可以 template.setEnableTransactionSupport(true);
- 配置参考:
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
// slf4j logger
private final static Logger logger = LoggerFactory.getLogger(RedisConfig.class);
@Bean
@Override
public KeyGenerator keyGenerator() {
logger.debug("----->>>>>[RedisConfig.keyGenerator]:Initializing Redis keyGenerator.");
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
@SuppressWarnings("rawtypes")
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
logger.debug("----->>>>>[RedisConfig.cacheManager]:Initializing simple Redis Cache manager.");
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
//todo 设置缓存过期时间
// rcm.setDefaultExpiration(60 * 3);//秒
return rcm;
}
/**
* 不用理会 factory 警告!!!
* todo 存对像时直接转成jsonString就行了,不需要用其它的序列化。
*
*
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
logger.debug("----->>>>>[RedisConfig.redisTemplate]:Initializing Redis Template.");
StringRedisTemplate template = new StringRedisTemplate(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
参考:
spring (boot)事务
spring 的事务主要用@Transactional注解。
有几点要特别注意:
- 指定rollbackFor参数,这个是显示指定回滚的条件,如rollbackFor = Exception.class,当方法抛异常时回滚,非常实用。
- 注意@Transactional只能作用在public的方法上
- @Transactional书写方便,尽可能写在最需要的地方,如某个方法上,而不是在整个类上
- 配置参考
@Configuration
@EnableTransactionManagement
@PropertySource("classpath:/application-database-${spring.profiles.active}.properties")
public class MyBatisConfig {
// @Bean(name = "dataSource") //!!!返回参数要是类,不是接口,否则它处无法使用!!!
// @ConfigurationProperties(prefix = "spring.datasource")
// public DruidDataSource dataSource() throws SQLException {
// return new DruidDataSource();
// }
/**
* 直接使用properties里面的配置生成datasource
*/
@Autowired
private DataSource dataSource;
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
//mybatis分页
PageHelper pageHelper = new PageHelper();
Properties props = new Properties();
props.setProperty("dialect", "mysql");
props.setProperty("reasonable", "true");
props.setProperty("supportMethodsArguments", "true");
props.setProperty("returnPageInfo", "check");
props.setProperty("params", "count=countSql");
pageHelper.setProperties(props); //添加插件
sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper});
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:*/mybatis/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() throws SQLException {
return new DataSourceTransactionManager(dataSource);
}
}
@EnableTransactionManagement 只需要这里指定一次就行了,其它地方不需要再指定,引用的时候自然会打开事务。