The main software versions used in writing this article are as follows.
The code below gets all ʻEMPNOs from a table called ʻEMP
and outputs them to standard output.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) {
String url = "jdbc:db2://<hostname>:<port>/<dbname>";
String user = "<user>";
String password = "<password>";
try (Connection con = DriverManager.getConnection(url, user, password)) {
con.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement("SELECT * FROM EMP");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("EMPNO"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
When I compile and run this source code, after printing all ʻEMPNO` to standard output, I get the following exception:
com.ibm.db2.jcc.am.SqlException: [jcc][t4][10251][10308][4.26.14]Java while transaction in progress on connection.sql.Connection.close()Was requested.
The transaction remains active and the connection cannot be closed. ERRORCODE=-4471, SQLSTATE=null
at com.ibm.db2.jcc.am.b7.a(b7.java:794)
at com.ibm.db2.jcc.am.b7.a(b7.java:66)
at com.ibm.db2.jcc.am.b7.a(b7.java:133)
at com.ibm.db2.jcc.am.Connection.checkForTransactionInProgress(Connection.java:1484)
at com.ibm.db2.jcc.t4.b.checkForTransactionInProgress(b.java:7581)
at com.ibm.db2.jcc.am.Connection.closeResourcesX(Connection.java:1507)
at com.ibm.db2.jcc.am.Connection.closeX(Connection.java:1493)
at com.ibm.db2.jcc.am.Connection.close(Connection.java:1470)
at Main.main(Main.java:22)
__java.sql.Connection.close ()
can be understood because try-catch-with-resource
calls it without permission, but in the first place," transaction remains active and connection cannot be closed ". What a mess ??? __.
In Db2, you need to commit the transaction with COMMIT
or ROLLBACK
before closing the DB connection. COMMIT
and ROLLBACK
are done only when you make changes to the DB data such as ʻINSERTand
DELETE, and
COMMITand
ROLLBACK are used for
SELECTthat only refers to the data. I'm sure there are many people who don't pay attention to-, but at least in Db2, you need to be aware of transactions even in the case of
SELECT`.
In the source code above, autocommit was turned off (con.setAutoCommit (false)
). If auto-commit = true, the jdbc driver will automatically commit when you call Connection :: close
, but if auto-commit = false, the programmer will explicitly Connection :: commit
or . If you do not call Connection :: rollback
, the transaction will not be committed. In other words, in the source code above, we turned off autocommit, so we tried to close the connection without confirming the transaction, resulting in ʻERRORCODE = -4471`.
--Call Connection :: commit
or Connection :: rollback
to explicitly complete the transaction
--Set auto-commit = true and throw the transaction completion to the JDBC Driver.
Is this the countermeasure (´ ・ ω ・ `)
Recommended Posts