先说结果
数据不一致
对外接口中事务部分成功,部分失败,导致数据异常

一个插入方法需要给不同业务插入数据,调用不同方法,部分表数据成功,部分表数据失败
代码调用链中事务有嵌套设置

外层异常,内层正常插入,导致数据异常,操作的是同以数据库,不同的代码包,用POM依赖调用
     原因分析:
         1.事务时效
             1.private、static、final的使用
             解决方法:不在类和方法上使用此类关键字
            2.通过this.xxx(调用当前类的方法)
             使用xml配置方式暴露代理对象.然后在service中通过代理对象AopContext.currentProxy()去调用方法。
         2.事务传递生效规则
             1.内部使用父层事务,如果父层级没有事务,开启新事务
2.方法内部多层级调用都需要支持事务回滚
pom中依赖的导致事务无法生效
决定用分布式锁redisson
import org.redisson.Redisson;
import org.redisson.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.redisson.api.RedissonClient;
/**
 * @Date 2022/2/8 20:29
 * @Version 1.0
 */
@Configuration
public class RedissionConfig {
    Logger log = LoggerFactory.getLogger(RedissionConfig.class);
    
    @Value("${spring.redis.host}")
    String redisIp;
    
    @Value("${spring.redis.port}")
    String redisPort;
    
    @Value("${spring.redis.password}")
    String redisPassword;
    
    @Bean(name="redissonClient")
    public RedissonClient init(){
        Config config = new Config();
        String url = "redis://"+redisIp+":"+redisPort;
        log.info(url);
        config.useSingleServer().setAddress(url).setPassword(redisPassword);
        config.useSingleServer().setConnectionMinimumIdleSize(10);
        RedissonClient redissonClient = Redisson.create(config);
        log.info("初始化RedissonClient成功");
        return redissonClient;
    }
}
 
业务代码中直接加锁解决
String dataKey = winnerCandidateVO.getDataKey();
RLock lock = redissonClient.getLock("stock:" + dataKey);
lock.lock(10, TimeUnit.SECONDS);  
lock.unlock(); 
通过加锁确保业务的完整唯一性,记得要释放锁
redisson自带有自旋锁和释放自己加的锁,不用担心多线程释放其他线程的锁










