Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 184505b

Browse files
committed
Attached is a patch that does the following:
1) improves performance of commit/rollback by reducing number of round trips to the server 2) uses 7.1 functionality for setting the transaction isolation level 3) backs out a patch from 11 days ago because that code failed to compile under jdk1.1 Details: 1) The old code was doing the following for each commit: commit begin set transaction isolation level xxx thus a call to commit was performing three round trips to the database. The new code does this in one round trip as: commit; begin; set transaction isolation level xxx In a simple test program that performs 1000 transactions (where each transaction does one simple select inside that transaction) has the following before and after timings: Client and Server on same machine old new --- --- 1.877sec 1.405sec 25.1% improvement Client and Server on different machines old new --- --- 4.184sec 2.927sec 34.3% improvement (all timings are an average of four different runs) 2) The driver was using 'set transaction isolation level xxx' at the begining of each transaction, instead of using the new 7.1 syntax of 'set session characteristics as transaction isolation level xxx' which only needs to be done once instead of for each transaction. This is done conditionally (i.e. if server is 7.0 or older do the old behaviour, else do the new behaviour) to not break backward compatibility. This also required the movement of some code to check/test database version numbers from the DatabaseMetaData object to the Connection object. 3) Finally while testing, I discovered that the code that was checked in 11 days ago actually didn't compile. The code in the patch for Connection.setCatalog() used Properties.setProperty() which only exists in JDK1.2 or higher. Thus compiling the JDBC1 driver failed as this method doesn't exist. Thus I backed out that patch. Barry Lind
1 parent dad8e41 commit 184505b

File tree

3 files changed

+112
-90
lines changed

3 files changed

+112
-90
lines changed

src/interfaces/jdbc/org/postgresql/Connection.java

Lines changed: 86 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import org.postgresql.core.Encoding;
1212

1313
/**
14-
* $Id: Connection.java,v 1.21 2001/07/30 14:51:19 momjian Exp $
14+
* $Id: Connection.java,v 1.22 2001/08/04 19:32:04 momjian Exp $
1515
*
1616
* This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
1717
* JDBC2 versions of the Connection class.
@@ -37,6 +37,9 @@ public abstract class Connection
3737
*/
3838
private Encoding encoding = Encoding.defaultEncoding();
3939

40+
private String dbVersionLong;
41+
private String dbVersionNumber;
42+
4043
public boolean CONNECTION_OK = true;
4144
public boolean CONNECTION_BAD = false;
4245

@@ -262,18 +265,19 @@ protected void openConnection(String host, int port, Properties info, String dat
262265
// used, so we denote this with 'UNKNOWN'.
263266

264267
final String encodingQuery =
265-
"select case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end";
268+
"case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end";
266269

267270
// Set datestyle and fetch db encoding in a single call, to avoid making
268271
// more than one round trip to the backend during connection startup.
269272

270273
java.sql.ResultSet resultSet =
271-
ExecSQL("set datestyle to 'ISO'; " + encodingQuery);
274+
ExecSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";");
272275

273276
if (! resultSet.next()) {
274277
throw new PSQLException("postgresql.con.failed", "failed getting backend encoding");
275278
}
276-
dbEncoding = resultSet.getString(1);
279+
dbVersionLong = resultSet.getString(1);
280+
dbEncoding = resultSet.getString(2);
277281
encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet"));
278282

279283
// Initialise object handling
@@ -904,8 +908,7 @@ public void setAutoCommit(boolean autoCommit) throws SQLException {
904908
if (autoCommit)
905909
ExecSQL("end");
906910
else {
907-
ExecSQL("begin");
908-
doIsolationLevel();
911+
ExecSQL("begin; " + getIsolationLevelSQL());
909912
}
910913
this.autoCommit = autoCommit;
911914
}
@@ -934,11 +937,7 @@ public boolean getAutoCommit() throws SQLException {
934937
public void commit() throws SQLException {
935938
if (autoCommit)
936939
return;
937-
ExecSQL("commit");
938-
autoCommit = true;
939-
ExecSQL("begin");
940-
doIsolationLevel();
941-
autoCommit = false;
940+
ExecSQL("commit; begin; " + getIsolationLevelSQL());
942941
}
943942

944943
/**
@@ -952,11 +951,7 @@ public void commit() throws SQLException {
952951
public void rollback() throws SQLException {
953952
if (autoCommit)
954953
return;
955-
ExecSQL("rollback");
956-
autoCommit = true;
957-
ExecSQL("begin");
958-
doIsolationLevel();
959-
autoCommit = false;
954+
ExecSQL("rollback; begin; " + getIsolationLevelSQL());
960955
}
961956

962957
/**
@@ -988,7 +983,7 @@ else if (message.indexOf("SERIALIZABLE") != -1)
988983
/**
989984
* You can call this method to try to change the transaction
990985
* isolation level using one of the TRANSACTION_* values.
991-
*
986+
*
992987
* <B>Note:</B> setTransactionIsolation cannot be called while
993988
* in the middle of a transaction
994989
*
@@ -999,29 +994,67 @@ else if (message.indexOf("SERIALIZABLE") != -1)
999994
* @see java.sql.DatabaseMetaData#supportsTransactionIsolationLevel
1000995
*/
1001996
public void setTransactionIsolation(int level) throws SQLException {
1002-
isolationLevel = level;
1003-
doIsolationLevel();
997+
//In 7.1 and later versions of the server it is possible using
998+
//the "set session" command to set this once for all future txns
999+
//however in 7.0 and prior versions it is necessary to set it in
1000+
//each transaction, thus adding complexity below.
1001+
//When we decide to drop support for servers older than 7.1
1002+
//this can be simplified
1003+
isolationLevel = level;
1004+
String isolationLevelSQL;
1005+
switch(isolationLevel) {
1006+
case java.sql.Connection.TRANSACTION_READ_COMMITTED:
1007+
if (haveMinimumServerVersion("7.1")) {
1008+
isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED";
1009+
} else {
1010+
isolationLevelSQL = getIsolationLevelSQL();
1011+
}
1012+
break;
1013+
1014+
case java.sql.Connection.TRANSACTION_SERIALIZABLE:
1015+
if (haveMinimumServerVersion("7.1")) {
1016+
isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE";
1017+
} else {
1018+
isolationLevelSQL = getIsolationLevelSQL();
1019+
}
1020+
break;
1021+
1022+
default:
1023+
throw new PSQLException("postgresql.con.isolevel",new Integer(isolationLevel));
1024+
}
1025+
ExecSQL(isolationLevelSQL);
10041026
}
10051027

10061028
/**
10071029
* Helper method used by setTransactionIsolation(), commit(), rollback()
1008-
* and setAutoCommit(). This sets the current isolation level.
1030+
* and setAutoCommit(). This returns the SQL string needed to
1031+
* set the isolation level for a transaction. In 7.1 and later it
1032+
* is possible to set a default isolation level that applies to all
1033+
* future transactions, this method is only necesary for 7.0 and older
1034+
* servers, and should be removed when support for these older
1035+
* servers are dropped
10091036
*/
1010-
protected void doIsolationLevel() throws SQLException {
1037+
protected String getIsolationLevelSQL() throws SQLException {
1038+
//7.1 and higher servers have a default specified so
1039+
//no additional SQL is required to set the isolation level
1040+
if (haveMinimumServerVersion("7.1")) {
1041+
return "";
1042+
}
10111043
String q = "SET TRANSACTION ISOLATION LEVEL";
10121044

10131045
switch(isolationLevel) {
10141046
case java.sql.Connection.TRANSACTION_READ_COMMITTED:
1015-
ExecSQL(q + " READ COMMITTED");
1016-
return;
1047+
q = q + " READ COMMITTED";
1048+
break;
10171049

10181050
case java.sql.Connection.TRANSACTION_SERIALIZABLE:
1019-
ExecSQL(q + " SERIALIZABLE");
1020-
return;
1051+
q = q + " SERIALIZABLE";
1052+
break;
10211053

10221054
default:
10231055
throw new PSQLException("postgresql.con.isolevel",new Integer(isolationLevel));
10241056
}
1057+
return q;
10251058
}
10261059

10271060
/**
@@ -1033,13 +1066,7 @@ protected void doIsolationLevel() throws SQLException {
10331066
*/
10341067
public void setCatalog(String catalog) throws SQLException
10351068
{
1036-
if(catalog!=null && !catalog.equals(PG_DATABASE)) {
1037-
close();
1038-
Properties info=new Properties();
1039-
info.setProperty("user", PG_USER);
1040-
info.setProperty("password", PG_PASSWORD);
1041-
openConnection(PG_HOST, PG_PORT, info, catalog, this_url, this_driver);
1042-
}
1069+
//no-op
10431070
}
10441071

10451072
/**
@@ -1095,4 +1122,31 @@ public String EscapeSQL(String sql) {
10951122
return sql;
10961123
}
10971124

1125+
/**
1126+
* What is the version of the server
1127+
*
1128+
* @return the database version
1129+
* @exception SQLException if a database access error occurs
1130+
*/
1131+
public String getDBVersionNumber() throws SQLException
1132+
{
1133+
if(dbVersionNumber == null) {
1134+
StringTokenizer versionParts = new StringTokenizer(dbVersionLong);
1135+
versionParts.nextToken(); /* "PostgreSQL" */
1136+
dbVersionNumber = versionParts.nextToken(); /* "X.Y.Z" */
1137+
}
1138+
return dbVersionNumber;
1139+
}
1140+
1141+
public boolean haveMinimumServerVersion(String ver) throws SQLException
1142+
{
1143+
if (getDBVersionNumber().compareTo(ver)>=0)
1144+
return true;
1145+
else
1146+
return false;
1147+
}
1148+
1149+
1150+
10981151
}
1152+

src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
4747
private static final byte defaultRemarks[]="no remarks".getBytes();
4848

4949

50-
private boolean haveMinimumServerVersion(String ver) throws SQLException
51-
{
52-
if (getDatabaseProductVersion().compareTo(ver)>=0)
53-
return true;
54-
else
55-
return false;
56-
}
57-
58-
5950
public DatabaseMetaData(Connection conn)
6051
{
6152
this.connection = conn;
@@ -126,7 +117,7 @@ public boolean isReadOnly() throws SQLException
126117
*/
127118
public boolean nullsAreSortedHigh() throws SQLException
128119
{
129-
return haveMinimumServerVersion("7.2");
120+
return connection.haveMinimumServerVersion("7.2");
130121
}
131122

132123
/**
@@ -159,7 +150,7 @@ public boolean nullsAreSortedAtStart() throws SQLException
159150
*/
160151
public boolean nullsAreSortedAtEnd() throws SQLException
161152
{
162-
return ! haveMinimumServerVersion("7.2");
153+
return ! connection.haveMinimumServerVersion("7.2");
163154
}
164155

165156
/**
@@ -182,14 +173,7 @@ public String getDatabaseProductName() throws SQLException
182173
*/
183174
public String getDatabaseProductVersion() throws SQLException
184175
{
185-
java.sql.ResultSet resultSet = connection.ExecSQL("select version()");
186-
resultSet.next();
187-
188-
StringTokenizer versionParts = new StringTokenizer(resultSet.getString(1));
189-
versionParts.nextToken(); /* "PostgreSQL" */
190-
String versionNumber = versionParts.nextToken(); /* "X.Y.Z" */
191-
192-
return versionNumber;
176+
return connection.getDBVersionNumber();
193177
}
194178

195179
/**
@@ -558,7 +542,7 @@ public boolean supportsExpressionsInOrderBy() throws SQLException
558542
*/
559543
public boolean supportsOrderByUnrelated() throws SQLException
560544
{
561-
return haveMinimumServerVersion("6.4");
545+
return connection.haveMinimumServerVersion("6.4");
562546
}
563547

564548
/**
@@ -581,7 +565,7 @@ public boolean supportsGroupBy() throws SQLException
581565
*/
582566
public boolean supportsGroupByUnrelated() throws SQLException
583567
{
584-
return haveMinimumServerVersion("6.4");
568+
return connection.haveMinimumServerVersion("6.4");
585569
}
586570

587571
/**
@@ -608,7 +592,7 @@ public boolean supportsGroupByBeyondSelect() throws SQLException
608592
*/
609593
public boolean supportsLikeEscapeClause() throws SQLException
610594
{
611-
return haveMinimumServerVersion("7.1");
595+
return connection.haveMinimumServerVersion("7.1");
612596
}
613597

614598
/**
@@ -749,7 +733,7 @@ public boolean supportsIntegrityEnhancementFacility() throws SQLException
749733
*/
750734
public boolean supportsOuterJoins() throws SQLException
751735
{
752-
return haveMinimumServerVersion("7.1");
736+
return connection.haveMinimumServerVersion("7.1");
753737
}
754738

755739
/**
@@ -761,7 +745,7 @@ public boolean supportsOuterJoins() throws SQLException
761745
*/
762746
public boolean supportsFullOuterJoins() throws SQLException
763747
{
764-
return haveMinimumServerVersion("7.1");
748+
return connection.haveMinimumServerVersion("7.1");
765749
}
766750

767751
/**
@@ -976,7 +960,7 @@ public boolean supportsPositionedUpdate() throws SQLException
976960
*/
977961
public boolean supportsSelectForUpdate() throws SQLException
978962
{
979-
return haveMinimumServerVersion("6.5");
963+
return connection.haveMinimumServerVersion("6.5");
980964
}
981965

982966
/**
@@ -1053,7 +1037,7 @@ public boolean supportsSubqueriesInQuantifieds() throws SQLException
10531037
*/
10541038
public boolean supportsCorrelatedSubqueries() throws SQLException
10551039
{
1056-
return haveMinimumServerVersion("7.1");
1040+
return connection.haveMinimumServerVersion("7.1");
10571041
}
10581042

10591043
/**
@@ -1075,7 +1059,7 @@ public boolean supportsUnion() throws SQLException
10751059
*/
10761060
public boolean supportsUnionAll() throws SQLException
10771061
{
1078-
return haveMinimumServerVersion("7.1");
1062+
return connection.haveMinimumServerVersion("7.1");
10791063
}
10801064

10811065
/**
@@ -1303,7 +1287,7 @@ public int getMaxCatalogNameLength() throws SQLException
13031287
*/
13041288
public int getMaxRowSize() throws SQLException
13051289
{
1306-
if (haveMinimumServerVersion("7.1"))
1290+
if (connection.haveMinimumServerVersion("7.1"))
13071291
return 1073741824; // 1 GB
13081292
else
13091293
return 8192; // XXX could be altered
@@ -1329,7 +1313,7 @@ public boolean doesMaxRowSizeIncludeBlobs() throws SQLException
13291313
*/
13301314
public int getMaxStatementLength() throws SQLException
13311315
{
1332-
if (haveMinimumServerVersion("7.0"))
1316+
if (connection.haveMinimumServerVersion("7.0"))
13331317
return 0; // actually whatever fits in size_t
13341318
else
13351319
return 16384;

0 commit comments

Comments
 (0)