Spring事务不回滚

问题:spring 声明式事务(非注解方式),多个操作的事务不能回滚,最后到网上找到了解决方法,但还是不怎么明白,主要原因是我在service方法里面try…catch了抛出的异常,后面把try…catch的代码改到了action中,问题解决事务可以回滚了,代码如下:

部分Service代码:

/**
 * <br>
 * <b>功能:</b>详细的功能描述<br>
 * <b>作者:</b>yanghong.zhou<br>
 * <b>日期:</b> Jul 9, 2012 <br>
 */
public class SkypeInfoServiceImpl implements SkypeInfoService {
    
    private SkypeInfoDao skypeInfoDao;
    
    public void setSkypeInfoDao(SkypeInfoDao skypeInfoDao) {
        this.skypeInfoDao = skypeInfoDao;
    }
    
    /**
     * 批量导入Skype账号信息Excel
     * @param path
     * @throws Exception
     */
    public String importExcel(String path) throws Exception {
        String msg = "";
//        try {
            // 获取后缀
            String suffixName = path.substring(path.lastIndexOf(".") + 1);
            if ("xls".equals(suffixName) || "et".equals(suffixName)
                    || "xlsx".equals(suffixName)) {
                File file = new File(path);
                String[][] result = getData(file);
                int rowLength = result.length;
                for (int i = 1; i < rowLength; i++) {
                    SkypeInfo vo = new SkypeInfo();
                    for (int j = 0; j < result[i].length; j++) {
                        if (result[0][j].equals("用户名")) {
                            if (result[i][j] != null && !result[i][j].equals("")) {
                            	
                            	SkypeInfo skepeInfo = skypeInfoDao.
                            			getSkypeInfoByName(result[i][j]);
								if (skepeInfo != null) {
									throw new ValidateException("第" + (i + 1)
											+ "行第" + (j + 1) + "列的用户名已存在,请重新输入");
								}
                            	
                                vo.setSkypeAccount(result[i][j]);
                            } else {
                                throw new ValidateException(
                                        "\u7b2c"
                                                + (i + 1)
                                                + "\u884c\u7b2c"
                                                + (j + 1)
                                                + "\u5217\u7684\u7528\u6237\u540d" +
                                                		"\u4e0d\u80fd\u4e3a\u7a7a");
                            }
                        }

                        if (result[0][j].equals("密码")) {
                            if (result[i][j] != null
                                    && !result[i][j].equals("")) {
                                vo.setSkypePass(result[i][j]);
                            } else {
                                // msg = "\u7b2c" + (i+1) + "\u884c\u7b2c" +
                                // (j+1) +
                                // "\u5217\u7684\u5bc6\u7801\u4e0d\u80fd\u4e3a\u7a7a";
                                throw new ValidateException(
                                        "\u7b2c"
                                                + (i + 1)
                                                + "\u884c\u7b2c"
                                                + (j + 1)
                                                + "\u5217\u7684\u5bc6\u7801" +
                                                		"\u4e0d\u80fd\u4e3a\u7a7a");
                            }
                        }

                    }
                    // 设置默认的角色
                    vo.setSkypeStatus(1);
                    vo.setAllotStatus(0);
                    // 执行新增的方法,向数据库中新增数据
                    insertSkypeInfo(vo);
                    msg = "导入Skype账号信息成功!";
                }
            } else {
                // msg = "\u8bf7\u4e0a\u4f20xls\u7c7b\u578b\u7684\u6587\u4ef6";
                throw new ValidateException(
                        "\u8bf7\u4e0a\u4f20xls\u7c7b\u578b\u7684\u6587\u4ef6");
            }
 //       } 
//    	catch (ValidateException e) {
//            e.printStackTrace();
//            msg = e.getMessage();
//        } catch (Exception e) {
//            e.printStackTrace();
//            msg = "导入失败,请联系管理员";
//        }
        return msg;
    }
}

原来的代码是在importExcel方法中try..catch异常,然后throw new ValidateException(),这个异常是一个继承RuntimeException的异常,然后在方法体部门继续往外抛。


部分Action代码:

/**
 * <br>
 * <b>功能:</b>详细的功能描述<br>
 * <b>日期:</b> Jul 9, 2012 <br>
 */
public class SkypeInfoAction extends DispatchAction {
    
    private SkypeInfoService skypeInfoService;
    
    public void setSkypeInfoService(SkypeInfoService skypeInfoService) {
        this.skypeInfoService = skypeInfoService;
    }
    
    /*
     * 批量上传Skype账号信息
     */
    public ActionForward batchUploadSkypeInfo(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        SkypeInfoForm vo = (SkypeInfoForm)form;
        FormFile file = vo.getFormFile();
        String fileName = file.getFileName();
        // 获取文件名
        String name = fileName.substring(0, fileName.lastIndexOf("."));
        // 获取当前时间
        Date date = new Date();
        String time = String.valueOf(date.getTime());
        // 获取后缀
        String suffix = fileName.substring(fileName.indexOf(".")+1);
        // 是否要限制文件上传的格式,可以根据suffix进行判断,需求未知,待定
        // 获取上传的路径
        String filePath = request.getSession().getServletContext().getRealPath("skypeinfo") + "\\" + name + time + "." + suffix;;
        String msg = "";
        try{
            InputStream input = file.getInputStream();
            OutputStream output = new FileOutputStream(new File(filePath));
            int read = 0;
            byte[] buffer = new byte[1024];
            while((read = input.read(buffer,0,1024))!=-1){
                output.write(buffer,0,read);
            }
            output.flush();
            output.close();
            input.close();
        }catch(IOException e){
            e.printStackTrace();
            //msg = "文件保存失败!";
        }
        try{
        	 msg = skypeInfoService.importExcel(filePath);
        }catch (ValidateException e) {
            e.printStackTrace();
            msg = e.getMessage();
        } catch (Exception e) {
            e.printStackTrace();
            msg = "导入失败,请联系管理员";
        }
       
        response.setContentType("text/html;charset=utf-8");
        try {
            PrintWriter outjs = response.getWriter();
            outjs.print("<script>alert('" + msg 
                 + "');this.location.href='skype.do?operator=toBatchAddSkypeInfo';</script>");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

原本中service层的try…catch转到Action层,也就是下面这部分代码:

try{
        msg = skypeInfoService.importExcel(filePath);
        }catch (ValidateException e) {
            e.printStackTrace();
            msg = e.getMessage();
        } catch (Exception e) {
            e.printStackTrace();
            msg = "导入失败,请联系管理员";
        }

原本红色部分实在service层处理异常的,但是事务回滚失败,从Excel文件中批量导入记录信息时,Skype帐号是不允许重复的,假如导入的第7条在数据库中存在,便前面的整个操作回滚,在service层try…catch的时候是不能回滚的,是不是我在service层把抛出的异常吞掉了,以置于spring不知道抛出了RuntimeException而不支持回滚操作!

你可能感兴趣的:(Spring事务不回滚)