Duang,最近搭建了一个自己的博客小破站,欢迎各位小伙伴来访吖:
ares-coder-blog-portalhttps://www.ares-stack.cn/blog_service/#/game
场景: 上传excel表,并将excel表中的数据构建成实体
<div class="pull-right" v-if="doc">
<el-upload
class="upload-demo"
ref="upload"
action="doUpload"
:limit="1"
:file-list="fileList"
:before-upload="beforeUpload">
<el-button slot="trigger" size="small" type="primary" :loading="requested" style="margin-right: 20px">上传excel</el-button>
<!-- <div slot="tip" class="el-upload__tip">只能上传excel文件,且不超过5MB</div>-->
<!-- <div slot="tip" class="el-upload-list__item-name">{{fileName}}</div>-->
</el-upload>
<!--<span slot="footer" class="dialog-footer">-->
<!-- <el-button @click="visible = false">取消</el-button>-->
<!-- <el-button type="primary" @click="submitUpload()">确定</el-button>-->
<!--</span>-->
</div>
beforeUpload(file){
// console.log(file,'文件');
this.files = file;
const extension = file.name.split('.')[1] === 'xls'
const extension2 = file.name.split('.')[1] === 'xlsx'
const isLt5M = file.size / 1024 / 1024 < 5
if (!extension && !extension2) {
this.$message.warning('上传模板只能是 xls、xlsx格式!')
return
}
if (!isLt5M) {
this.$message.warning('上传模板大小不能超过 5MB!')
return
}
this.fileName = file.name;
setTimeout(() => {
this.submitUpload();
},500);
return false; // 返回false不会自动上传
},
// 上传excel
submitUpload() {
console.log('上传'+this.files.name)
if(this.fileName == ""){
this.$message.warning('请选择要上传的文件!')
return false
}
let fileFormData = new FormData();
fileFormData.append("code", "t_pathology_info_excel");
fileFormData.append("description", "excel上传测试");
//filename是键,file是值,就是要传的文件,test是要传的文件名
fileFormData.append('files', this.files, this.fileName);
let requestConfig = {
headers: {
'Content-Type': 'multipart/form-data'
},
}
// 执行上传excel
let id = '';
this.http.postJson('/sys/file/upload', fileFormData, requestConfig).then(resp => {
if (resp.data.status != 200) {
this.$message.error("excel上传失败,请重新上传");
} else {
id = resp.data.result[0].attachmentId;
}
}).catch((e) => {
// console.log(e);
this.$message.error("excel上传失败,请重新上传");
}).finally(() => {
if(id) {
// 触发生成订单实体数据
this.generateBill(id);
}
});
}
// 构建实体
generateBill(attachmentId) {
this.http.postJson('/admin/myTest/leadingIn/' + attachmentId + '/type_one').then(resp => {
if (resp.data.status != 200) {
// this.$message.error("excel上传失败,请重新上传");
} else {
this.$message.success("excel上传成功!");
this.query();
}
}).catch((e) => {
// console.log(e);
// this.$message.error("excel上传失败,请重新上传");
}).finally(() => {
});
}
在这里遇到了死锁:Lock wait timeout exceeded; try restarting transaction
我在将excel表中的数据构建成实体的方法中加入了:@Transactional(rollbackOn = RuntimeException.class) 注解
手动抛异常throw new RuntimeException(); 正常应该是出现异常自动回滚,但是这里出现是事务锁,将数据库的附件表锁死了
猜想原因:一开始上传的附件,没有绑定关联id,而是选择了在构建实体方法中:先绑定关联,然后根据关联
取出excel表。由于上传附件的方法是异步执行的,报了异常事务回滚,出现事务锁将数据库的附件表锁死了。
解决办法:
1,数据库对应的表需要解锁,解决:Lock wait timeout exceeded try restarting transaction__夜渐凉的博客-CSDN博客
2,在上传附件的方法中,同时将关联id绑定
/**
* 文件上传&绑定relId excel上传诊单数据
*
* @param userId 当前登录人Id
* @param username 当前登陆用户名称
* @param code 上传编码标识code
* @param des 描述
* @param files 附件
*/
@PostMapping(value = "/sys/file/upload4excelImport")
public Message upload4excelImport(@CurrentUser Long userId, @CurrentUser String username, @CurrentUser("relId") Long relId,
@RequestParam(name = "code") String code, @RequestParam(name = "des") String des,
@RequestParam MultipartFile[] files) {
// 第一步,generateAttachment本地生成附件方法
// 第二步,绑定附件表关联id
return Message.success();
}