问题: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而不支持回滚操作!