前不久写过一篇高效大批量制造MySQL数据的文章:《如何利用LoadRunner最高效的批量制造MySQL数据》,后来有人问我,怎么高效大批量制造Oracle数据。其实是一样的,也是用JDBC的批量插入(addBatch)方法,以下就提供一下我写的脚本,以供参考:
/*
* LoadRunner Java script. (Build: _build_number_)
*
* Script Description:
*
*/
import lrapi.lr;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.lang.StringBuffer;
import java.util.List;
import java.util.ArrayList;
public class Actions
{
//设定数据库驱动,数据库连接地址、端口、名称,用户名,密码
String driverName="oracle.jdbc.OracleDriver";
String url="jdbc:oracle:thin:@192.168.1.176:1521:orcl";
String user="test"; //用户名
String password="123456"; //密码
PreparedStatement pstmt = null;
//数据库连接对象
Connection conn = null;
public void connection(){
try {
//反射Oracle数据库驱动程序类
Class.forName(driverName);
//获取数据库连接
conn = DriverManager.getConnection(url, user, password);
// 关闭事务自动提交
conn.setAutoCommit(false);
//输出数据库连接
System.out.println(conn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void deconnection(){
try{
if(pstmt != null){
pstmt.close();
}
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public void addBatchData(List alist){
try{
for (int i = 0; i < alist.size(); i++) {
pstmt.setString((i+1), alist.get(i).toString());
}
//把一个SQL命令加入命令列表
pstmt.addBatch();
} catch (Exception e) {
e.printStackTrace();
}
}
public int init() throws Throwable {
return 0;
}//end of init
public int action() throws Throwable {
String sqlStr="insert into test_opadetail(id, opaid, pripid, uniscid, entname, enttype, enttype_cn, regorg, " +
"regorg_cn, lerep, regno, certype, cerno, specause, specause_cn, abntime, decorg, decorg_cn, ismove, " +
"remexcpres, remexcpres_cn, remdate, redecorg, redecorg_cn, creationtime, creatoruserid, lastmodificationtime, " +
"lastmodifieruserid, deletiontime, deleteruserid, isdeleted, dom, enttype_zn, year)" +
" values " +
"(sys_guid(), ?, ?, ?, ?, ?, ?, '220101', '长春市工商行政管理局', 'test', ?, '', '', 1, " +
"'未按规定公示年报', to_date(to_char(sysdate,'yyyy/mm/dd'),'YYYY/MM/DD'), '220101', '长春市工商行政管理局', 1," +
" '', '', '', '', '', to_date(to_char(sysdate,'YYYY/MM/DD HH24:MI:SS'),'YYYY/MM/DD HH24:MI:SS'), " +
"'97e6daadd18f4667be0c5c42b84b8a90', to_date(to_char(sysdate,'YYYY/MM/DD HH24:MI:SS'),'YYYY/MM/DD HH24:MI:SS'), " +
"'97e6daadd18f4667be0c5c42b84b8a90', '', '', 0, ?, ?, '')";
List list = new ArrayList();//定义一组参数化数据
list.add(lr.eval_string("{Param1}"));
list.add(lr.eval_string("{Param2}"));
list.add(lr.eval_string("{Param3}"));
list.add("TEST"+lr.eval_string("{Param4}"));
list.add(lr.eval_string("{Param5}"));
list.add(lr.eval_string("{Param6}"));
list.add(lr.eval_string("{Param7}"));
list.add(lr.eval_string("TESTA-{Param4}"));
list.add(lr.eval_string("{Param12}"));
connection();
StringBuffer sql = new StringBuffer();
sql.append(sqlStr);
lr.start_transaction("action");
try{
//创建该连接下的PreparedStatement对象
pstmt = conn.prepareStatement(sql.toString());
for (int k=0;k<1000;k++){//一个User一批次插入1000条
addBatchData(list);
}
// 执行批量更新
pstmt.executeBatch();
} catch (Exception e) {
e.printStackTrace();
}
lr.end_transaction("action", lr.AUTO);
deconnection();
return 0;
}//end of action
public int end() throws Throwable {
return 0;
}//end of end
}
然后通过Loadrunner进行多用户并发的跑脚本,快速的制造出成千上亿条数据,我就是用这个方法,在测试环境中模拟出现场的大数据量,然后去重现或定位系统当中由于慢SQL引起的慢事务问题。
注:以上是批量插入数据的脚本,有人会将批量更新也放到脚本中执行,这时候就要避免行级锁在高并发时引起死锁,所以强调更新条件应该使用主键。