日期:2014-05-18  浏览次数:20698 次

高并发下死锁问题,分析好久想不明白
开发了日报功能,在做压力测试的时候,新建的时候报死锁,调试了好久,不明白产生的原因。

通过日志发现,这些并发可以穿插执行,但是新增和删除不是会加意向排他锁,在事务没提交结束前,其他线程怎么能会都执行到
this.eventTagService.save(event, tags);

看日志,死锁都是在建立关系的时候发生的,望各位指点下!先谢啦!



业务场景:用户填写一条日程数据,包括日程内容和一些标签,日程内容放在记录表A上,标签都在一张信息表B上,无重复

表:A表  B表  AB表(关联表)

代码逻辑
1、数据插入表A

2、迭代标签,查找B表,如果有返则回数据,无则插入后返回

3、在AB表插入数据,建立关联


结果在压力测试的时候,发现有死锁
报错:
org.hibernate.exception.LockAcquisitionException


2013-12-24 17:00:00 [http-8888-14:3236837] - [WARN] SQL Error: 1213, SQLState: 40001
2013-12-24 17:00:00 [http-8888-14:3236837] - [ERROR] Deadlock found when trying to get lock; try restarting transaction



用的注解事务,数据库是mysql 
代码:

@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public Event save(Event event) {
        try {
            logger.info(Thread.currentThread().getName()+":日志新增开始");
            if (event.getId() == null) {
            
                this.fillForSave(event);
            
            } 

            logger.info(Thread.currentThread().getName()+":event开始--新增");
            this.eventDao.save(event);
            logger.info(Thread.currentThread().getName()+":event结束--新增");
            
            
            this.follow(event);
            logger.info(Thread.currentThread().getName()+":日志新增结束");
            return event;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(Thread.currentThread().getName()+e.getMessage());
            return null;
        }
    }



private void follow(Event event){
        logger.info(Thread.currentThread().getName()+":tags开始");
        List<Tag> tags = this.tagService.saveTags(event.getClassifications(), TagType.Normal);
        logger.info(Thread.currentThread().getName()+":tags结束");
        
        if(tags==null || tags.size()==0){