其中句柄数pstmt-200 达到200个,连接数conn-1只有一个
此时相关参数为:
MAX_SESSIONS = 100#最大会话数
MAX_SESSION_STATEMENT = 200#一个会话最大的句柄数
可以通过调大MAX_SESSION_STATEMENT参数暂时解决问题,但无法从根本上解决问题。
可以使用查看连接会话的句柄使用情况
select sql_text,state,n_stmt "句柄的容量",n_used_stmt as "使用的句柄数",curr_sch,user_name,trx_id,create_time,clnt_type,clnt_ip,run_status from v$sessions;
在代码可以看到在for循环中除参数的传递之外还有一个
prest = con.prepareStatement(sql1);
寻其源码:
有这样的解释,通过传入含有占位符的sql语句返回PreparedStatement对象,通过对PreparedStatement的操作进而转化为为对数据库的操作,在这个对象类中的方法我们可以看到如此多的方法,这些方法提供了占位符转化为指定参数的等功能
addBatch
将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中。通过调用方法 executeBatch 可以批量执行此列表中的命令。
executeBatch()将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
通过以上的分析我将代码改写为
使得每次循环时不将会创建预编译的 SQL 语句的对象,这样便避免的句柄的增加
解决问题
附件:
1.实体类
package dm_02;
import java.io.InputStream;
import java.io.StringReader;
/**
* @类名 Testyy1.java
* @作者 li2025
* @版本 V1.0
* @日期 2020年6月30日-下午3:10:19
* @描述
*
*/
public class Testyy1 {
private int C1=1;
private String C2;
private Double C3;
private long C4;
private StringReader C5;
private InputStream C6;
public Testyy1() {
super();
// TODO Auto-generated constructor stub
}
public Testyy1(int c1, String c2, Double c3, long c4, StringReader c5, InputStream c6) {
super();
C1 = c1;
C2 = c2;
C3 = c3;
C4 = c4;
C5 = c5;
C6 = c6;
}
public int getC1() {
return C1;
}
public void setC1(int c1) {
C1 = c1;
}
public String getC2() {
return C2;
}
public void setC2(String c2) {
C2 = c2;
}
public Double getC3() {
return C3;
}
public void setC3(Double c3) {
C3 = c3;
}
public long getC4() {
return C4;
}
public void setC4(long c4) {
C4 = c4;
}
public StringReader getC5() {
return C5;
}
public void setC5(StringReader c5) {
C5 = c5;
}
public InputStream getC6() {
return C6;
}
public void setC6(InputStream c6) {
C6 = c6;
}
}
2.Conect配置
package dm_02;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Conn {
Connection con=null;
public Connection getConn(){
String cname="dm.jdbc.driver.DmDriver";
String url="jdbc:dm://127.0.0.1:5236?logDir=E:\\big_date\\DM&logLevel=all";//DM7的端口号为5236
String userid="SYSDBA";
String pwd="SYSDBA";
try{
Class.forName(cname);
con=DriverManager.getConnection(url,userid,pwd);
System.out.println();
}catch(Exception e){
System.out.println("数据库连接失败:"+e.getMessage());
}
return con;
}
public void disConn() throws SQLException{
if(con!=null){
con.close();
}
}
}
3.方法类
package dm_02;
import java.io.*;
import java.sql.*;
import java.util.Date;
public class Stmt {
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
PreparedStatement prest=null;
Conn connect=new Conn();
int m=20;
//测试建表
public void stmt_create() throws SQLException, FileNotFoundException{
String sql1_d = "drop table TESTYYL;";
String sql1 = "create table TESTYYL(C1 int,C2 VARCHAR(100),C3 number(10,2),C4 timestamp,C5 clob,C6 blob);";
con = connect.getConn();
stmt = con.createStatement();
try {
stmt.executeUpdate(sql1);
} catch (SQLException e) {
// 表已存在则创建失败,删除表并重新创建
stmt.executeUpdate(sql1_d);
stmt.executeUpdate(sql1);
}
System.out.println("建表成功成功!");
stmt.close();
con.close();
connect.disConn();
}
//循环插入10条记录
public void stmt_insert() throws SQLException, FileNotFoundException{
String sql1 = "insert into testyyl values(?,?,?,?,?,?);";
con = connect.getConn();
Statement stmt=con.createStatement();
con.setAutoCommit(false);
prest = con.prepareStatement(sql1);
int i = 0;
int j=12222;
String str = "达梦数据库";
File file = new File("test_info\\pic.jpg");
long t = System.nanoTime();// 获取当期时间,单位为纳秒
Testyy1[] testyy1s=new Testyy1[m];
for (i = 0; i < m; i++) {
StringReader vclob = new StringReader(str);
InputStream vblob = new FileInputStream(file);
testyy1s[i]=new Testyy1(j++, "wuhandameng", Math.random(), new Date().getTime(), vclob, vblob);
}
for (i = 1; i <= m; i++) {
//prest = con.prepareStatement(sql1);
prest.setInt(1, testyy1s[i-1].getC1());
prest.setString(2, testyy1s[i-1].getC2());
prest.setDouble(3, testyy1s[i-1].getC3());
prest.setTimestamp(4, new java.sql.Timestamp(testyy1s[i-1].getC4()));
prest.setClob(5,testyy1s[i-1].getC5() ); //也可以直接用prest.SetString("达梦数据库");
prest.setBlob(6, testyy1s[i-1].getC6());
prest.addBatch();
}
prest.executeBatch();
con.commit();
t = (System.nanoTime() - t) / 1000000;
System.out.println("插入" + (i - 1) + "行记录耗时:" + t + "毫秒");
stmt.close();
con.close();
connect.disConn();
}
//删除
public void stmt_delete() throws SQLException, FileNotFoundException{
String sql1="delete from testyyl where c1=? and c2=?";
con=connect.getConn();
con.setAutoCommit(false);
prest=con.prepareStatement(sql1);
int i = 0;
for(i = 1; i <= m; i++){
prest.setInt(1, i);
prest.setString(2, "wuhandameng");
prest.addBatch();
//prest.executeBatch();
}
prest.executeBatch();
con.commit();
System.out.println("删除"+(i-1)+"条记录成功!");
prest.close();
con.close();
connect.disConn();
}
public void stmt_select() throws SQLException, FileNotFoundException{
String sql1="select * from testyyl;";
con=connect.getConn();
Statement stmt=con.createStatement();
ResultSet rs1=stmt.executeQuery(sql1);
while(rs1.next()){
System.out.println(
rs1.getInt(1)+","+
rs1.getString(2)+","+
rs1.getDouble(3)+","+
rs1.getTimestamp(4)+","+
rs1.getString(5)+","+ //rs1.getClob(5)
rs1.getBlob(6) //rs1.getBytes(6)
);
}
rs1.close();
stmt.close();
con.close();
connect.disConn();
}
}
4.main入口
package dm_02;
public class Dm_Demo {
public static void main(String[] args) throws Exception{
Stmt st1=new Stmt();
//st1.stmt_delete();
//st1.stmt_create();
st1.stmt_insert();
//st1.stmt_select();
//st1.stmt_delete();
//st1.stmt_select();
}
}
更多资讯请上达梦技术社区了解: https://eco.dameng.com