我第一次使用java中的连接池。我正在编写的应用程序是部署在oracle glassfish 3.1上的Web应用程序,资源连接池由它处理。我在连接对象上将自动提交设置为false,由javax.sql.DataSource返回,但在代码中,rollback命令根本没有任何效果。所有先前的写操作都是自动提交的。 java代码中是否还有其他设置可以禁用自动提交?或者我必须在glassfish上进行一些配置设置?
我使用的数据库是Oracle 10g。
我在这里发布了一些给我问题的代码:
private int importFile(String id, String fileName, String label,
String prosumerId, String districtCodes)
throws IOException,
SQLException {
logger.debug("Importing file [" + fileName + "]");
File f = new File(fileName);
BufferedReader br = null;
Calendar cal = new GregorianCalendar();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
String query = "insert into TB_SDK_USER_FILES values ("
+ id + ", '" + label + "', '"
+ fileName.substring(fileName.lastIndexOf("/") + 1) + "', 'active', "
+ "to_date('" + sdf.format(new Date(cal.getTimeInMillis())) + "', 'dd/mm/yyyy hh24:mi:ss'), "
+ "to_date('" + sdf.format(new Date(cal.getTimeInMillis())) + "', 'dd/mm/yyyy hh24:mi:ss'), "
+ "'" + prosumerId + "'"
+ ") ";
logger.debug("Executing query [" + query + "]");
dbl.openDBConnection();
int x = dbl.set(query);
if (x <= 0) {
dbl.rollback();
dbl.closeDBConnection();
logger.error("Insert in TB_SDK_USER_FILES failed, stopping execution ");
return -3;
}
PreparedStatement ps = null;
String line = new String();
try {
br = new BufferedReader(new FileReader(f));
query = "insert into TB_SDK_CONTENTS "
+ "(id, contentCode, cli, content, contentType, PROSUMERID, cld, email) "
+ "values (?,?,?,?,?,?,?,?)";
logger.debug("Executing query [" + query + "]");
ps = dbl.getPreparedStatement(query);
while ((line = br.readLine()) != null) {
String[] tmp = line.split("\t");
if (tmp.length < 4) {
logger.debug("Sono presenti erroneamente meno di 4 valori!!!!");
br.close();
f.delete();
dbl.rollback();
ps.close();
dbl.closeDBConnection();
return -2;
}
ps.setInt(1, new Integer(id).intValue());
String test = tmp[0].replace("*", "");
logger.debug("first column: test [" + test + "]");
try {
if (test.length() > 0) {
double testDouble = Double.parseDouble(test);
//int testInt = Integer.parseInt(test);
}
} catch (NumberFormatException nfe) {
logger.error("The first column does not satisfy the format requested. Found [" + tmp[0] + "] -- NumberFormatException");
dbl.rollback();
ps.close();
dbl.closeDBConnection();
br.close();
f.delete();
return -6;
}
if (tmp[0].length() > 0) {
ps.setString(2, tmp[0].trim());
} else {
logger.error("The first column does not satisfy the format requested. Found [" + tmp[0] + "] -- length() <= 0");
dbl.rollback();
ps.close();
dbl.closeDBConnection();
br.close();
f.delete();
return -6;
}
test = tmp[1].replace("*", "").trim();
logger.debug("second column: test [" + test + "]");
try {
if (test.length() > 0) {
double testDouble = Double.parseDouble(test);
//int testInt = Integer.parseInt(test);
}
} catch (NumberFormatException nfe) {
logger.error("The second column does not satisfy the format requested. Found [" + tmp[1] + "]");
dbl.rollback();
ps.close();
dbl.closeDBConnection();
br.close();
f.delete();
return -7;
}
if (tmp[1].length() > 0) {
ps.setString(3, tmp[1].trim());
} else {
logger.error("The second column does not satisfy the format requested. Found [" + tmp[1] + "] -- length() <= 0");
dbl.rollback();
ps.close();
dbl.closeDBConnection();
br.close();
f.delete();
return -7;
}
logger.debug("third column: tmp[2] [" + tmp[2] + "]");
ps.setString(4, tmp[2]);
if ((tmp[3].length() > 0) && ((tmp[3].compareToIgnoreCase("TTS") == 0)
|| (tmp[3].compareToIgnoreCase("Audio") == 0))) {
ps.setString(5, tmp[3].trim());
logger.debug("fourth column: tmp[3] [" + tmp[3] + "]");
} else {
logger.error("The fourth column does not satisfy the format requested. Found [" + tmp[3] + "]");
dbl.rollback();
ps.close();
dbl.closeDBConnection();
br.close();
f.delete();
return -10;
}
ps.setString(6, prosumerId);
if (tmp.length > 4) {
tmp[4] = tmp[4].trim();
if ((tmp[4].length() > 0) && (tmp[4].length() <= 12) && (tmp[4].matches("^\\d*$"))) {
boolean ok = false;
logger.debug("Checking district codes...");
String[] codes = districtCodes.split(",");
for (int i = 0; i < codes.length; i++) {
if (tmp[4].startsWith(codes[i].trim())) {
ok = true;
logger.debug("District code found.");
break;
}
}
if (ok) {
ps.setString(7, tmp[4]);
logger.debug("fifth column: tmp[4] [" + tmp[4] + "]");
} else {
logger.error("The fifth column does not satisfy the format requested. Found [" + tmp[4] + "]");
dbl.rollback();
ps.close();
dbl.closeDBConnection();
br.close();
f.delete();
return -8;
}
} else if (tmp[4].length() == 0) {
ps.setString(7, "-");
logger.debug("fifth column: tmp[4] [-]");
} else {
logger.error("The fifth column does not satisfy the format requested. Found [" + tmp[4] + "]");
dbl.rollback();
ps.close();
dbl.closeDBConnection();
br.close();
f.delete();
return -8;
}
} else {
ps.setString(7, "-");
}
if (tmp.length == 6) {
tmp[5] = tmp[5].trim();
if ((tmp[5].length() > 0) && (isValidEmailAddress(tmp[5]))) {
ps.setString(8, tmp[5]);
} else if (tmp[5].length() == 0) {
ps.setString(8, "-");
} else {
logger.error("The sixth column does not satisfy the format requested. Found [" + tmp[5] + "]");
dbl.rollback();
ps.close();
dbl.closeDBConnection();
br.close();
f.delete();
return -9;
}
} else {
ps.setString(8, "-");
}
x = ps.executeUpdate();
if (x <= 0) {
dbl.rollback();
ps.close();
dbl.closeDBConnection();
br.close();
//f.delete();
logger.error("Insert in TB_SDK_CONTENTS failed, stopping execution ");
return -3;
}
}
br.close();
//f.delete();
ps.close();
dbl.commit();
dbl.closeDBConnection();
return 0;
} catch (Exception ex) {
logger.error("An exception occured during the import of file [" + fileName + "] for line [" + line + "]", ex);
dbl.rollback();
if (br != null) {
br.close();
}
if (ps != null) {
ps.close();
}
dbl.closeDBConnection();
//f.delete();
return -1;
}
}
在处理数据库操作的另一个类上:
public int set(String query) {
Statement statement = null;
int ris = -1;
try {
if (connection == null || !connection.isValid(1)) connect();
logger.debug("Opening statement");
statement = connection.createStatement();
ris = statement.executeUpdate(query);
} catch (SQLException ex) {
logger.error("ERROR in execution of [" + query + "] due to: ", ex);
ris = -1;
} finally {
try {
logger.debug("Closing statement");
if (statement != null) {
statement.close();
}
} catch (SQLException ex1) {
logger.error("ERROR cannot close statement.", ex1);
}
}
return ris;
}
连接打开:
public boolean connect() {
if (dataSource != null) {
try {
connection = dataSource.getConnection();
logger.info("Connection open to DB");
return true;
} catch (SQLException ex) {
logger.error("An error occured during request of connection to datasource, due to...", ex);
return false;
}
}
String url;
if (connectionString.length() > 0) {
url = connectionString;
} else {
url = "jdbc:oracle:thin:@" + host + ":" + port + ":" + sid;
}
try {
// create an OracleDataSource
OracleDataSource ods = new OracleDataSource();
// set connection properties
Properties prop = new Properties();
prop.put("user", user);
prop.put("password", pwd);
ods.setConnectionProperties(prop);
ods.setURL(url);
// get the connection
connection = ods.getConnection();
connection.setAutoCommit(false);
((OracleConnection) connection).setDefaultRowPrefetch(10);
logger.info("Connection open to DB");
return true;
} catch (Exception ex) {
logger.info("An exception occured in execution of [connect]. ");
if (dataSource == null) {
logger.error("[" + url + ", " + user + ", " + pwd + "] ERROR in execution of [connect] due to: ", ex);
}
return false;
}
}
dataSource getConnection():
public static Connection getConnection() throws SQLException {
Connection con = dataSource.getConnection();
con.setAutoCommit(false);
return con;
}
数据源的查找在上下文创建时在Context Listener中完成。
修改 我正在阅读关于池连接的使用的oracle教程以及关于它的其他链接:每个例子打开和关闭池的连接都是在同一个方法中完成的。我认为只需要更简单地解释所有步骤,但我想知道这是否也不需要满足连接池级别的“事务”。谁能证实我这个?或者给我一个文档链接,这里有很好的解释?非常感谢你!