Springboot注解事务隔离性无效

框架用的SpringBoot2.1.3 + MyBatis-Plus
有一个方法里面要对mysql一张表进行上百次的 为空插入非空更新操作
写好后开jmeter测一下发现插入大量重复数据
所以想通过串行事务的方式来

@Transactional(propagation=Propagation.REQUIRES_NEW,isolation=Isolation.serializable,readOnly = false)

但是这个注解并没有起作用,我试着手动在方法里抛异常,能够正常的回滚,就是依然不能串行的执行
之后尝试在给表加上唯一索引,现在是没有重复数据了,但是mybatis一直疯狂的抛重复key的异常,更新操作依旧没有执行,因为回滚了

方法是public修饰的
Service类也用@Service注解了的

就是建立的类有些不一样
Service是将多个实例注入到map中取的

public interface IBase{
    void a();
    // ....
}
// 这个虚基类里有部分抽象方法,其他有大量的公共方法
public abstract class Base impl IBase{
    @Overwired
    public void a(){
        //....
        func();
    }
    
    public abstract void func();
    // ...
}

@Service("a")
public class A extends Base{
    @Overwired
    @Transactional(propagation=Propagation.REQUIRES_NEW,isolation=Isolation.serializable,readOnly = false)
    public void func(){
        // 大量的为空插入非空更新操作
        // ...
    }
}

之后由Controller调用

@Controller
public class BaseController impl IBaseController {
    @Autowried
    private Map<IBase> map;
    
    @Overwired
    public void test(String str){
        map.get(str).a();
    }
}

项目是用Netty搞TCP长连接的,所以其实没有Springboot的Web层
我就在NettyHandler的Read函数中,利用SpringContext.getBean(Clazz)方式获取IBaseController来执行test()方法,流程就是这样主要就是想让A.func()串行执行来保证能够正常
用Jemter开几百个线程,只有部分能更新,其余的全部抛异常,究竟咋回事啊?

其实我觉得用串行的隔离性太慢了,或者有没有什么更好的方式避免这种问题
比较更新我部分用的on duplicate key update,感觉能提升一点效率,但是听说这个会导致死锁,很郁闷

阅读 3.5k
4 个回答

解决了。。
因为NettyHandler没有交给ioc管理,就擅自用SpringContext获取Controller的Bean
注入到一个private变量中了
这个变量应该用static修饰并通过static代码块来初始化

private static IBaseController controller;
static {
    controller = SpringUtils.getBean(IBaseController.class);
} 

然后事务隔离性就正常了
自己太蔡了

你的Controller为什么要使用全局变量?

新手上路,请多包涵

我也遇到过一回,然后我是另起了一个service,分别注入就可以了

新手上路,请多包涵

你这个解决方案完全不支持分布式呃。。。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题