高并发下死锁问题,分析好久想不明白
开发了日报功能,在做压力测试的时候,新建的时候报死锁,调试了好久,不明白产生的原因。
通过日志发现,这些并发可以穿插执行,但是新增和删除不是会加意向排他锁,在事务没提交结束前,其他线程怎么能会都执行到
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;
}
}