一个典型的事务使用错误分析

下面是我在开发中遇到一个事务使用错误案例

try {	// buisness operation	ut = Trans.getUserTransaction();	ut.begin();	if ("add".equals(actionType)) {		addAccutor(moduleName, productId, liabId, accutor,				nextExecuteOrder);	} else if ("delete".equals(actionType)) {		deleteAccutor(moduleName, productId, liabId, listId);	} else if ("changeInputSource".equals(actionType)) {		changeInputSource(moduleName, inputSource, listId);	} else if ("moveup".equals(actionType)) {		moveUpAccutor(moduleName, listId);	} else if ("movedown".equals(actionType)) {		moveDownAccutor(moduleName, listId);	}	ut.commit();	// load Data	loadData(moduleName, request, form, productId, liabId);	return mapping.findForward("AccutorBenefit");} catch (Exception e) {	if (ut != null) {		try {			ut.rollback();		} catch (Exception e1) {			throw ExceptionFactory.parse(e1);		}	}	throw ExceptionFactory.parse(e);}

上面代码会有几种执行情况:
没异常发生时,不会有任何问题(这好像是废话);
有异常发生时,若异常发生在ut.commit之前没有问题;
若在执行loadData(moduleName, request, form, productId, liabId)发生异常,开始执行异常捕获,首先执行事务回滚,这是事务早已回滚,所以抛出No active Transaction.
这就导致最后抛出的是异常1,而在这之前抛出的异常2被虚拟机丢了,这和bruce eckel在thinking in java中讲到的java异常缺陷类似,都是丢掉前面的异常,抛出一个不相干异常.
改正方式:
1.其实这个地方不需要使用事务,删掉事务代码
2.把commit放到return之前执行
总结:
这里有两点值得我们关注:
1.这种错误的使用事务方式,导致了问题,以及改正方式
2.错误使用java异常机制的场景,vm丢掉了异常.

异常1
java.lang.IllegalStateException: No active Transaction	at com.evermind.server.ApplicationServerTransactionManager.rollback(ApplicationServerTransactionManager.java:398)	at com.company.pub.util.internal.DBTransaction.rollback(DBTransaction.java:108)	at com.company.lf.product.ctrl.accutor.AccutorBenefitAction.process(AccutorBenefitAction.java:74)	at com.company.pub.framework.GenericAction.execute(GenericAction.java:250)	at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)	at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)	at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)	at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)	at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)	at com.evermind.server.http.ResourceFilterChain.doFilter(ResourceFilterChain.java:65)	at com.company.pub.framework.XssFilter.doFilter(XssFilter.java:96)	at com.evermind.server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:16)	at com.company.pub.framework.AppFilter.doFilter(AppFilter.java:83)	at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:600)	at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:317)	at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:790)	at com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:208)	at com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:125)	at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:192)	at java.lang.Thread.run(Thread.java:534)
异常2
java.lang.NullPointerException	at java.lang.Class.forName0(Native Method)	at java.lang.Class.forName(Class.java:141)	at com.company.lf.product.bo.product.MaintainModule.loadData(MaintainModule.java:231)	at com.company.lf.product.ds.productlife.DataMaintainDSImpl.loadData(DataMaintainDSImpl.java:68)	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)	at java.lang.reflect.Method.invoke(Method.java:324)	at com.company.pub.framework.internal.DSProxy.invoke(DSProxy.java:98)	at $Proxy5.loadData(Unknown Source)	at com.company.lf.product.ds.productlife.DataMaintainDSDelegate.loadData(DataMaintainDSDelegate.java:52)	at com.company.lf.product.ctrl.accutor.AccutorBenefitAction.loadData(AccutorBenefitAction.java:346)	at com.company.lf.product.ctrl.accutor.AccutorBenefitAction.process(AccutorBenefitAction.java:65)	at com.company.pub.framework.GenericAction.execute(GenericAction.java:250)	at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)	at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)	at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)	at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)	at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)	at com.evermind.server.http.ResourceFilterChain.doFilter(ResourceFilterChain.java:65)	at com.company.pub.framework.XssFilter.doFilter(XssFilter.java:96)	at com.evermind.server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:16)	at com.company.pub.framework.AppFilter.doFilter(AppFilter.java:83)	at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:600)	at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:317)	at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:790)	at com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:208)	at com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:125)	at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:192)	at java.lang.Thread.run(Thread.java:534)


你可能感兴趣的:(java,apache,thread,servlet,struts)