HennyChen 2008-09-01
今天在数据库连接字符串中看到了selectMethod=cursor
知道了这个用法如下:
作用:以利用服务器端的游标加快速度
使用情况:
1.执行多个Statements的操作的时候用
2.需要手动使用事务的时候使用以上是在使用sqlserver数据库的连接字符串的时候使用过。
例如:jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=071008_03;SelectMethod=cursor
但是今天我将其用在oracle数据库的时候,却报出了一下的错误信息:
Io 异常: Connection refused(DESCRIPTION=(TMP=)(VSNNUM=169869824)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))
这是个老话题,2002年在使用ejb的bmp就遇到了这个问题
连接数据库成功之后,想在一个事务中初始化多个预处理句柄时报错
dbConn.setAutoCommit(false)
for(inti=0;i<5;i++){
pstmt[i]=dbConn.prepareStatement(strPreSQL[i]);
错误提示:
java.sql.SQLException:[Microsoft][SQLServer2000DriverforJDBC]Can'tstartmanualtransactionmodebecausethereareclonedconnections
怀疑MSSQL不能在一个事务中建多个预处理句柄
Resolution:
Youhavetoaddapropertytothepooldefinition,somethingtodowithselectMode=cursororselectMethod=cursor.Checkthedriverdocumentation.Otherwisethedriverwillnotallowmorethanonestatementperconnectionatanygiventime
微软的专家告诉的
ThiserroroccurswhenyoutrytoexecutemultiplestatementsagainstaSQLServerdatabasewiththeJDBCdriverwhileinmanualtransactionmode(AutoCommit=false)andwhileusingthedirect(SelectMethod=direct)mode.Directmodeisthedefaultmodeforthedriver."
importjava.sql.*;
importjava.io.*;
publicclassRepro{
publicstaticvoidmain(Stringargs[])
{
try{
Connectioncon;
Statements1=null;
ResultSetr1=null;
Statements2=null;
ResultSetr2=null;
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
con=DriverManager.getConnection(
"jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs;SelectMethod=Direct;User=User;Password=Password");
//fix1
//"jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs;SelectMethod=Cursor;User=User;Password=Password");
con.setAutoCommit(false);
try{
s1=con.createStatement();
r1=s1.executeQuery("SELECT*FROMauthors");
//fix2
//r1.close();
//s1.close();
s2=con.createStatement();
r2=s2.executeQuery("SELECT*FROMpublishers");
}
catch(SQLExceptionex)
{
System.out.println(ex);
}
}
catch(Exceptione)
{
e.printStackTrace();
}
}
}
用SQLServer驱动一次select很多数据最好在connectionstring中加上SelectMethod=Cursor,以利用服务器端游标加快速度,其实不只sqlserver,oracle的jdbc,只要使用PreparedStatement,驱动默认就使用游标,sqlserver则不然,必须使用SelectMethod=Cursor才打开游标。
这点在使用jotm时,并且使用Xapool时,必须修改DataSourceFactory,把PreparedStatementPool禁掉,否则记录插的太快了,很可能是游标没来得及关闭
即使不使用jotm,大量向oracle插入数据,例如每毫秒1条,也会引发游标用完,所以大量插入数据时,应该使用oracle的批处理batchupdate.
可惜的是,微软的sqlserver的jdbc驱动不支持这个属性