在做性能测试的时候,有时候会遇到下面的错误:
This Vuser already started a transaction with the same name, and has not yet processed the corresponding lr_end_transaction statement.
解释:就是脚本中有一个事物开始了,但是没有结束事物,此时loadrunner就会报错,因为开始和结束是一一对应的,谁也不能把它们拆开,拆开了就会报错。
查看脚本如下:
import java.lang.String;
import java.rmi.Naming;
import java.util.*;
import lrapi.lr;
import com.paic.pafa.app.biz.ac.impl.ApplicationControllerBean;
import com.paic.pafa.app.biz.ac.impl.ApplicationControllerHome;
import com.paic.pafa.app.biz.ac.impl.ApplicationControllerRemote;
import com.paic.pafa.app.biz.service.BusinessServiceException;
import com.paic.pafa.app.dto.*;
import com.paic.pafa.app.lwc.core.beans.BeansException;
public class Actions
{
com.paic.pafa.app.biz.ac.impl.ApplicationControllerRemote remote = null;
public int init() throws Throwable {
DummyClassLoader.setContextClassLoader();
com.paic.pafa.app.biz.ac.impl.ApplicationControllerHome home = null;
try{
java.util.Properties p = new java.util.Properties();
p.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
p.put(javax.naming.Context.PROVIDER_URL, "
p.put(javax.naming.Context.SECURITY_PRINCIPAL, "V_BANK_BIS_BANK_BIB_100");
p.put(javax.naming.Context.SECURITY_CREDENTIALS, "zqb5S17P");
javax.naming.InitialContext ic = new javax.naming.InitialContext(p);
Object homeobj = ic.lookup("ejb/bib/PafaAC");
home = (com.paic.pafa.app.biz.ac.impl.ApplicationControllerHome)javax.rmi.PortableRemoteObject.narrow(homeobj, com.paic.pafa.app.biz.ac.impl.ApplicationControllerHome.class);
} catch (javax.naming.NamingException e) {
e.printStackTrace();
}
try {
lr.start_transaction("appctrlhome_create");
remote = home.create();
lr.end_transaction("appctrlhome_create", lr.AUTO);
} catch (Throwable t) {
lr.end_transaction("appctrlhome_create", lr.FAIL);
t.printStackTrace();
}
return 0;
}
public int action(){
ServiceResponse serviceResponse = null;
ServiceRequest serviceRequest = new ServiceRequest();
Map responseMap = new HashMap();
Map resultMap = new HashMap();
Map headMap = new HashMap();
String resultCode = new String();
String resultMsg = new String();
String STAT= new String();
String ADDWORD= new String();
Map msgHeadmap_in = new HashMap();
Map msgHeadmap = new HashMap();
Map msgbodyMap_in = new HashMap();
Map msgbodyMap = new HashMap();
msgHeadmap_in.put("TRAN_CODE","100201"); //电信局_后台扣费
msgHeadmap_in.put("PARTNER_CODE","1002");
msgHeadmap_in.put("TRAN_CHANNEL","TER");
msgHeadmap_in.put("REQUEST_SERIAL","
msgHeadmap_in.put("REQUEST_DATE","20101110");
msgHeadmap_in.put("REQUEST_TIME","14:48:57");
msgHeadmap_in.put("ORIGINAL_REQUEST_SERIAL","");
msgHeadmap_in.put("FRONT_SERIAL","");
msgHeadmap_in.put("REGION_CODE","000000");
msgHeadmap.put("MSG_HEAD",msgHeadmap_in);
msgbodyMap_in.put("BUSICODE","601"); //项目代码BUSICODE
msgbodyMap_in.put("BANKNO","12"); //银行代号BANKNO
msgbodyMap_in.put("KFCODE","KF"); //KF KFCODE
msgbodyMap_in.put("USERID","22222224"); //号码 USERID
msgbodyMap_in.put("ACCT","
msgbodyMap_in.put("MONAMT","0.01"); //月话费MONAMT
msgbodyMap_in.put("DELAMT","0.00"); //滞纳金 DELAMT
msgbodyMap_in.put("PREAMR1","0.00"); //预扣费1 PREAMR1
msgbodyMap_in.put("PREMON1","0000"); //预扣费月份1 PREMON1
msgbodyMap_in.put("PREAMR2","0.00"); //预扣费2 PREAMR2
msgbodyMap_in.put("PREMON2","0000"); //预扣费月份2 PREMON2
msgbodyMap_in.put("TOLAMT","0.01"); //总扣费额TOLAMT
msgbodyMap.put("MSG_BODY",msgbodyMap_in);
Map outMap = new HashMap();
outMap.putAll(msgHeadmap);
outMap.putAll(msgbodyMap);
serviceRequest.setCurrentRequestObject(outMap);
serviceRequest.setRequestedServiceID("dispatchAction");
lr.think_time(15);
try {
lr.start_transaction("电信局_后台扣费");
serviceResponse = remote.handleRequest(serviceRequest);
responseMap = (Map)serviceResponse.getModel();
resultMap=(Map)responseMap.get(ServiceResponse.SERVICE_RESPONSE_RESULT);
headMap = (Map)resultMap.get("MSG_HEAD");
resultCode = (String)headMap.get("RESULT_CODE"); //结果代码 写在头部信息里
resultMsg = (String)headMap.get("RESULT_MESSAGE"); //结果代码 写在头部信息里
if (resultCode.equals("0000")) {
lr.end_transaction("电信局_后台扣费",lr.PASS);
}
else {
lr.end_transaction("电信局_后台扣费",lr.FAIL);
}
} catch (Throwable t) {
t.printStackTrace();
}
lr.message(resultCode);
return 0;
}//end of action
public int end() throws Throwable {
return 0;
}
}
分析:由于错误提示是transaction ,所以主要看插入事物的脚本部分,根据提示可以断定,程序在进入lr.start_transaction后,在end_transaction前就异常了,所以并没有执行end_transaction,就会报这个错误,这个分析可能一时难以想到,还有一种简单的办法,就是执行脚本,然后看Replay Log,此时可以看到一个红色的异常,内容如下:Error: Vuser started transaction "电信局_后台扣费", but did not reached a corresponding end transaction statement. The transaction ended automatically with status 'fail'.
根据这个就很容易判断了。
解决办法:
根据上面的分析,此脚本的容错性很差,修改只要把事物的开始和结束放到try的外面即可,脚本如下:
import java.lang.String;
import java.rmi.Naming;
import java.util.*;
import lrapi.lr;
import com.paic.pafa.app.biz.ac.impl.ApplicationControllerBean;
import com.paic.pafa.app.biz.ac.impl.ApplicationControllerHome;
import com.paic.pafa.app.biz.ac.impl.ApplicationControllerRemote;
import com.paic.pafa.app.biz.service.BusinessServiceException;
import com.paic.pafa.app.dto.*;
import com.paic.pafa.app.lwc.core.beans.BeansException;
public class Actions
{
com.paic.pafa.app.biz.ac.impl.ApplicationControllerRemote remote = null;
public int init() throws Throwable {
DummyClassLoader.setContextClassLoader();
com.paic.pafa.app.biz.ac.impl.ApplicationControllerHome home = null;
try{
java.util.Properties p = new java.util.Properties();
p.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
p.put(javax.naming.Context.PROVIDER_URL, "
p.put(javax.naming.Context.SECURITY_PRINCIPAL, "V_BANK_BIS_BANK_BIB_100");
p.put(javax.naming.Context.SECURITY_CREDENTIALS, "zqb5S17P");
javax.naming.InitialContext ic = new javax.naming.InitialContext(p);
Object homeobj = ic.lookup("ejb/bib/PafaAC");
home = (com.paic.pafa.app.biz.ac.impl.ApplicationControllerHome)javax.rmi.PortableRemoteObject.narrow(homeobj, com.paic.pafa.app.biz.ac.impl.ApplicationControllerHome.class);
} catch (javax.naming.NamingException e) {
e.printStackTrace();
}
try {
lr.start_transaction("appctrlhome_create");
remote = home.create();
lr.end_transaction("appctrlhome_create", lr.AUTO);
} catch (Throwable t) {
lr.end_transaction("appctrlhome_create", lr.FAIL);
t.printStackTrace();
}
return 0;
}
public int action(){
ServiceResponse serviceResponse = null;
ServiceRequest serviceRequest = new ServiceRequest();
Map responseMap = new HashMap();
Map resultMap = new HashMap();
Map headMap = new HashMap();
String resultCode = new String();
String resultMsg = new String();
String STAT= new String();
String ADDWORD= new String();
Map msgHeadmap_in = new HashMap();
Map msgHeadmap = new HashMap();
Map msgbodyMap_in = new HashMap();
Map msgbodyMap = new HashMap();
msgHeadmap_in.put("TRAN_CODE","100201"); //电信局_后台扣费
msgHeadmap_in.put("PARTNER_CODE","1002");
msgHeadmap_in.put("TRAN_CHANNEL","TER");
msgHeadmap_in.put("REQUEST_SERIAL","
msgHeadmap_in.put("REQUEST_DATE","20101110");
msgHeadmap_in.put("REQUEST_TIME","14:48:57");
msgHeadmap_in.put("ORIGINAL_REQUEST_SERIAL","");
msgHeadmap_in.put("FRONT_SERIAL","");
msgHeadmap_in.put("REGION_CODE","000000");
msgHeadmap.put("MSG_HEAD",msgHeadmap_in);
msgbodyMap_in.put("BUSICODE","601"); //项目代码BUSICODE
msgbodyMap_in.put("BANKNO","12"); //银行代号BANKNO
msgbodyMap_in.put("KFCODE","KF"); //KF KFCODE
msgbodyMap_in.put("USERID","22222224"); //号码 USERID
msgbodyMap_in.put("ACCT","
msgbodyMap_in.put("MONAMT","0.01"); //月话费MONAMT
msgbodyMap_in.put("DELAMT","0.00"); //滞纳金 DELAMT
msgbodyMap_in.put("PREAMR1","0.00"); //预扣费1 PREAMR1
msgbodyMap_in.put("PREMON1","0000"); //预扣费月份1 PREMON1
msgbodyMap_in.put("PREAMR2","0.00"); //预扣费2 PREAMR2
msgbodyMap_in.put("PREMON2","0000"); //预扣费月份2 PREMON2
msgbodyMap_in.put("TOLAMT","0.01"); //总扣费额TOLAMT
msgbodyMap.put("MSG_BODY",msgbodyMap_in);
Map outMap = new HashMap();
outMap.putAll(msgHeadmap);
outMap.putAll(msgbodyMap);
serviceRequest.setCurrentRequestObject(outMap);
serviceRequest.setRequestedServiceID("dispatchAction");
lr.think_time(15);
lr.start_transaction("电信局_后台扣费");
try {
serviceResponse = remote.handleRequest(serviceRequest);
responseMap = (Map)serviceResponse.getModel();
resultMap=(Map)responseMap.get(ServiceResponse.SERVICE_RESPONSE_RESULT);
headMap = (Map)resultMap.get("MSG_HEAD");
resultCode = (String)headMap.get("RESULT_CODE"); //结果代码 写在头部信息里
resultMsg = (String)headMap.get("RESULT_MESSAGE"); //结果代码 写在头部信息里
} catch (Throwable t) {
t.printStackTrace();
}
if (resultCode.equals("0000")) {
lr.end_transaction("电信局_后台扣费",lr.PASS);
}
else {
lr.end_transaction("电信局_后台扣费",lr.FAIL);
}
lr.message(resultCode);
return 0;
}//end of action
public int end() throws Throwable {
return 0;
}
}
此时运行的时候就不会有这种错误提示了,问题得到解决。