在springmvc中,事物的配置都是通过配置文件进行配置的,在工程中我们经常会在一个类的内部,通过方法之间的调用,来完成,数据入库操作,但是往往在类内部通过方法之间调用方法完成入库操作时,我们配置的事物没有生效。就比如 方法B是数据库操作方法,它使用@Transactional(propagation = Propagation.REQUIRES_NEW) (传播特性自己根据需要设置) 注解标记,方法A去调用方法B的时候,无论方法A是否添加了注解,B的事物都不会生效。
例如:
/**
* @ClassName CreatePdfServiceImpl
* @Description
* @Author Administrator
* @Date 2020/6/23 10:23
**/
@Service("createPdfService")
public class CreatePdfServiceImpl implements CreatePdfService {
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void pdfHandler(PbsEleInvoiceInfoTmp pbsEleInvoiceInfoTmp) throws Exception{
Map<String, Map<String, Object>> stringMap = reqDataConvet(pbsEleInvoiceInfoTmp.getEnvoiceInfo());
pbsEleInvoiceInfoTmp.setUpdateTime(IfspDateTime.getYYYYMMDDHHMMSS());
String name = createFileName();
try {
//判断生成pdf是否成功
if (createPdfFile(stringMap,name)){
//判断pdf签名是否成功 -否
NetSignResult netSignResult = pafFileSign(name);
if (IfspDataVerifyUtil.isBlank(netSignResult)){
pbsEleInvoiceInfoTmp.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_2);
}else {//成功
//上传pdf文件
String fileName = PDFUploadUti.sendImage(netSignResult.getByteArrayResult(NetSignResult.SIGN_TEXT), name);
if (IfspDataVerifyUtil.isNotBlank(fileName)){
pbsEleInvoiceInfoTmp.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_0);
pbsEleInvoiceInfoTmp.setDownloadUri(fileName);
}else {
pbsEleInvoiceInfoTmp.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_4);
}
}
}else {//pdf生成失败
pbsEleInvoiceInfoTmp.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_1);
}
} catch (Exception e) {
log.error("电子发票生成失败!原因:{}",e.getMessage());
pbsEleInvoiceInfoTmp.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_2);
}finally {
//直接调用pdfHandler方法,这里即使出现异常也不会出现回滚
checkFIleExit(name,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);
if (Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_0.equals(pbsEleInvoiceInfoTmp.getPdfStatus())){
pbsEleInvoiceInfoTmpDao.deleteByPrimaryKey(pbsEleInvoiceInfoTmp.getTxnOrderId());
pbsEleInvoiceInfoDao.insertSelectiveTmp(pbsEleInvoiceInfoTmp);
}else {
Integer valueOf = Integer.valueOf(pbsEleInvoiceInfoTmp.getPrintNum());
valueOf++;
pbsEleInvoiceInfoTmp.setPrintNum(valueOf.toString());
log.info("更新数据。。。{}",IfspFastJsonUtil.objectTomap(pbsEleInvoiceInfoTmp));
pbsEleInvoiceInfoTmpDao.updateByPrimaryKeySelective(pbsEleInvoiceInfoTmp);
}
}
}
/**
*@author lxw
*@date 2020/7/3
*@desc pdf文件生成处理
*@param []
*@return com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse
**/
@Override
public MchtPfdOprResponse createPdfHandler() throws Exception{
//查询所有没有处理数据
long startTime = System.currentTimeMillis();
log.info("开始时间:{}",startTime);
MchtPfdOprResponse response = new MchtPfdOprResponse();
int pageNo = 1;
int pageSize = Integer.valueOf(Constants.PDF_CREATE_AND_SIGN.PDF_PAGESIZE);
while (true){
List<PbsEleInvoiceInfoTmp> pbsEleInvoiceInfoTmps = pbsEleInvoiceInfoTmpDao.queryInfoList(pageNo,pageSize);
if (IfspDataVerifyUtil.isBlank(pbsEleInvoiceInfoTmps)||pbsEleInvoiceInfoTmps.size()==0){
response.setRespMsg("电子发票生成完成!");
break;
}
for (PbsEleInvoiceInfoTmp pbsEleInvoiceInfoTmp : pbsEleInvoiceInfoTmps) {
try {
//这里直接调用pdfHandler方法,pdfHandler的事物是不会生效的
pdfHandler(pbsEleInvoiceInfoTmp);
} catch (Exception e) {
log.error("电子发票生成异常:{}",e.getMessage());
continue;
}
}
if (pbsEleInvoiceInfoTmps.size()!=0){
pageNo = pageSize+1;
pageSize = pageNo+Integer.valueOf(Constants.PDF_CREATE_AND_SIGN.PDF_PAGESIZE)-1;
}
}
log.info("结束时间:{},共耗时:{}ms",System.currentTimeMillis(),System.currentTimeMillis()-startTime);
return response;
}
}
这是因为,当我们直接调用pdfHandler方法的时候,通过编译我们可以看到createPdfHandler方法中是通过 this.pdfHandler() 内部调用的。这就是说我方法调用没有通过spring代理去调用,造成了注解@Transactional 没有生效(注解不生效是因为,注解功能实现是通过Aop实现的,不使用Spring就相当于没有用Aop注解功能也就无效了),所有注解的方法即使添加了事物的注解,spring 不认。所以想在方法内部调用带有注解的方法只能先去spring容器中将该类取出来,然后去再通过这个容器中的代理类调用方法,事物就会生效了
例如:
/**
* @ClassName CreatePdfServiceImpl
* @Description
* @Author Administrator
* @Date 2020/6/23 10:23
**/
@Service("createPdfService")
public class CreatePdfServiceImpl implements CreatePdfService {
@Resource
private PbsEleInvoiceInfoDao pbsEleInvoiceInfoDao;
@Resource
private PbsEleInvoiceInfoTmpDao pbsEleInvoiceInfoTmpDao;
//获取spring容器中的createPdfService
@Resource
private CreatePdfService createPdfService;
private Logger log = IfspLoggerFactory.getLogger(CreatePdfServiceImpl.class);
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void pdfHandler(PbsEleInvoiceInfoTmp pbsEleInvoiceInfoTmp) throws Exception{
Map<String, Map<String, Object>> stringMap = reqDataConvet(pbsEleInvoiceInfoTmp.getEnvoiceInfo());
pbsEleInvoiceInfoTmp.setUpdateTime(IfspDateTime.getYYYYMMDDHHMMSS());
String name = createFileName();
try {
//判断生成pdf是否成功
if (createPdfFile(stringMap,name)){
//判断pdf签名是否成功 -否
NetSignResult netSignResult = pafFileSign(name);
if (IfspDataVerifyUtil.isBlank(netSignResult)){
pbsEleInvoiceInfoTmp.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_2);
}else {//成功
//上传pdf文件
String fileName = PDFUploadUti.sendImage(netSignResult.getByteArrayResult(NetSignResult.SIGN_TEXT), name);
if (IfspDataVerifyUtil.isNotBlank(fileName)){
pbsEleInvoiceInfoTmp.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_0);
pbsEleInvoiceInfoTmp.setDownloadUri(fileName);
}else {
pbsEleInvoiceInfoTmp.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_4);
}
}
}else {//pdf生成失败
pbsEleInvoiceInfoTmp.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_1);
}
} catch (Exception e) {
log.error("电子发票生成失败!原因:{}",e.getMessage());
pbsEleInvoiceInfoTmp.setPdfStatus(Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_2);
}finally {
checkFIleExit(name,Constants.PDF_CREATE_AND_SIGN.PDF_FILE_PATH);
if (Constants.PDF_CREATE_AND_SIGN.PDF_FILE_CREATE_STATUS_0.equals(pbsEleInvoiceInfoTmp.getPdfStatus())){
pbsEleInvoiceInfoTmpDao.deleteByPrimaryKey(pbsEleInvoiceInfoTmp.getTxnOrderId());
pbsEleInvoiceInfoDao.insertSelectiveTmp(pbsEleInvoiceInfoTmp);
}else {
Integer valueOf = Integer.valueOf(pbsEleInvoiceInfoTmp.getPrintNum());
valueOf++;
pbsEleInvoiceInfoTmp.setPrintNum(valueOf.toString());
log.info("更新数据。。。{}",IfspFastJsonUtil.objectTomap(pbsEleInvoiceInfoTmp));
pbsEleInvoiceInfoTmpDao.updateByPrimaryKeySelective(pbsEleInvoiceInfoTmp);
}
}
}
/**
*@author lxw
*@date 2020/7/3
*@desc pdf文件生成处理
*@param []
*@return com.ruim.ifsp.merser.bean.response.MchtPfdOprResponse
**/
@Override
public MchtPfdOprResponse createPdfHandler() throws Exception{
//查询所有没有处理数据
long startTime = System.currentTimeMillis();
log.info("开始时间:{}",startTime);
MchtPfdOprResponse response = new MchtPfdOprResponse();
int pageNo = 1;
int pageSize = Integer.valueOf(Constants.PDF_CREATE_AND_SIGN.PDF_PAGESIZE);
while (true){
List<PbsEleInvoiceInfoTmp> pbsEleInvoiceInfoTmps = pbsEleInvoiceInfoTmpDao.queryInfoList(pageNo,pageSize);
if (IfspDataVerifyUtil.isBlank(pbsEleInvoiceInfoTmps)||pbsEleInvoiceInfoTmps.size()==0){
response.setRespMsg("电子发票生成完成!");
break;
}
for (PbsEleInvoiceInfoTmp pbsEleInvoiceInfoTmp : pbsEleInvoiceInfoTmps) {
try {
//为了使事务生效,必须通过sping代理调用方法后,事务才会生效
createPdfService.pdfHandler(pbsEleInvoiceInfoTmp);
} catch (Exception e) {
log.error("电子发票生成异常:{}",e.getMessage());
continue;
}
}
if (pbsEleInvoiceInfoTmps.size()!=0){
pageNo = pageSize+1;
pageSize = pageNo+Integer.valueOf(Constants.PDF_CREATE_AND_SIGN.PDF_PAGESIZE)-1;
}
}
log.info("结束时间:{},共耗时:{}ms",System.currentTimeMillis(),System.currentTimeMillis()-startTime);
return response;
}
}