首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2EE开发 >

高并发下死锁有关问题,分析好久想不明白

2014-01-09 
高并发下死锁问题,分析好久想不明白开发了日报功能,在做压力测试的时候,新建的时候报死锁,调试了好久,不明

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

通过日志发现,这些并发可以穿插执行,但是新增和删除不是会加意向排他锁,在事务没提交结束前,其他线程怎么能会都执行到
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){
            tags = new ArrayList<Tag>(); 
            tags.add(this.tagService.saveTag("默认", TagType.Normal));
        }
        
        if (event.getProjectId() != null && event.getProjectId() != -1) {
            tags.add(this.tagService.saveTag(event.getProjectName(), TagType.Project));
            tags.add(this.tagService.saveTag(event.getWorkTypeName(), TagType.JobType));
        }
        
        logger.info(Thread.currentThread().getName()+":关系开始");
        this.eventTagService.save(event, tags);
        logger.info(Thread.currentThread().getName()+":关系结束");
        
        this.attentionService.eventUpdate(event.getCreator());
    }



@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public List<EventTag> save(Event event, List<Tag> tags) {
        //保存之前,删除旧的
        logger.info(Thread.currentThread().getName()+":删除关系开始");
        this.deleteEventTagByEventId(event.getId());
        logger.info(Thread.currentThread().getName()+":删除关系结束");
        


        //this.eventTagDao.flush();
        //保存新的
        logger.info(Thread.currentThread().getName()+":建立关系开始");
        List<EventTag> eventTags = new ArrayList<EventTag>();
        if(tags != null && tags.size() != 0) {
            for(Tag tag : tags) {
                EventTag eventTag = new EventTag(event, tag);
                this.eventTagDao.save(eventTag);
                logger.info(Thread.currentThread().getName()+":建立关系");
                eventTags.add(eventTag);
            }
        }
        logger.info(Thread.currentThread().getName()+":建立关系结束");
        return eventTags;
    }




@Override
    public Tag saveTag(String tagName, TagType tagType) {
        Tag tag = this.get(tagName, tagType);
        
        if(tag == null) {
            tag = new Tag(tagName, tagType);
            this.tagDao.save(tag);
        }
        
        return tag;
    }
    
    
    /**
     * 批量保存标签
     */
    @Override
    public List<Tag> saveTags(String tagNames, TagType tagType) {
        List<String> names = TagUtils.convert(tagNames);
        List<Tag> tags = new ArrayList<Tag>();
        if(names == null || names.size() == 0) {
            return tags;
        } else {
            for(String name : names) {
                Tag tag = this.saveTag(name, tagType);
                tags.add(tag);
            }
            return tags;
        }
    }





[解决办法]
涉及到线程安全的问题了。sychronized 解决
[解决办法]
这个建议采用存储过程执行,
func_** 
begin
lock table ** in exclusive mode;
 do
end
这样多线程是能确保正常

热点排行