JDBC事务--自动提交
通过MYSQLIO执行IO操作。
commit=true/false,代码执行是一样的,都flush出去了,只是服务器端没有执行。
package com.zhuguang.jack.jdbc; import java.sql.*; public class JDBCTransationTest { public static void main(String[] args) { Connection connection = null; try { connection = getConnection(); connection.setAutoCommit(false);// 执行之后不提交事务。对于Select没有影响, 但对于Insert和Update的话, 没有提交数据就不会被修改 // 用法大多数是在要执行多条语句才提交。 insertTest(connection); // insertTest1(connection); connection.commit(); connection.rollback(); } catch (ClassNotFoundException e) { } catch (SQLException e) { try { connection.rollback();//只要执行有异常,就要rollback , 这一步必不可少 //如果没有在执行出现异常的时候进行回滚。如果在执行第一条语句之后出现异常, //con既没有提交也没有回滚,表就会被锁住(如果oracle数据库就是行锁),而这个锁却没有机会释放。 } catch (SQLException e1) { } } finally { if (connection != null) { try { selectAll(connection); connection.close();// 关闭Connection的代码有被Mark掉, 是想呈现conn.setAutoCommit(false)的效果。 // 原因是在 Connection Close的时候会执行一次Commit. // 而如果Connection是在应用服务器中使用连接池的话, Connection就不会被Close, 也就不会执行Commit. //可能在执行con.close()的时候会释放锁,但还是如果应用服务器使用了数据库连接池,连接不会被断开。 } catch (SQLException e) { } } } } public static void insertTest(Connection con) throws SQLException { PreparedStatement stmt = con.prepareStatement("insert into money(name,money) values (?,?)"); stmt.setString(1, "JACK2"); stmt.setDouble(2, 100.0); stmt.executeUpdate(); System.out.println("Data inserted successfully"); stmt.close(); } public static void insertTest1(Connection con) throws SQLException { PreparedStatement stmt = con.prepareStatement("insert into money(name,money) values (?,?)"); stmt.setString(1, "JACK3"); stmt.setDouble(2, 100.10); stmt.executeUpdate(); System.out.println("Data inserted successfully"); stmt.close(); } public static void selectAll(Connection con) throws SQLException { Statement st = con.createStatement(); ResultSet rs = st.executeQuery("select * from money"); System.out.println("============test============"); while (rs.next()) { System.out.println(rs.getString("momey")); } ResultSet rs1 = st.executeQuery("select * from money"); System.out.println("============test1============"); while (rs1.next()) { System.out.println(rs1.getString("momey")); } st.close(); } public static Connection getConnection() throws ClassNotFoundException, SQLException { Connection con = null; Class.forName("com.mysql.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/account?useUnicode=true&characterEncoding=utf-8&useSSL=false", "root", "123456"); System.out.println("DB Connection created successfully"); return con; } }
Class.forName("com.mysql.jdbc.Driver"); public class Driver extends NonRegisteringDriver implements java.sql.Driver { static { try { java.sql.DriverManager.registerDriver(new Driver()); //把Driver给注册到自己的驱动程序管理器(DriverManager)中 } public Driver() throws SQLException { } }
Class.forName得到的class是已经初始化完成的 Classloder.loaderClass得到的class是没有初始化的 public static synchronized void registerDriver(java.sql.Driver driver, DriverAction da) { if(driver != null) { registeredDrivers.addIfAbsent(new DriverInfo(driver, da)); } }
public static Connection getConnection(String url, String user, String password) { java.util.Properties info = new java.util.Properties(); return (getConnection(url, info, Reflection.getCallerClass())); }
private static Connection getConnection( String url, java.util.Properties info, Class<?> caller) { for(DriverInfo aDriver : registeredDrivers) { if(isDriverAllowed(aDriver.driver, callerCL)) { try { Connection con = aDriver.driver.connect(url, info); if (con != null) { return (con); //com.mysql.jdbc.JDBC4Connection@221af3c0 } } } } }
NonRegisteringDriver类: public Connection connect(String url, Properties info) { Connection newConn = com.mysql.jdbc.ConnectionImpl.getInstance(host(props), port(props), props, database(props), url); //props = {HOST=127.0.0.1, user=root, HOST.1=127.0.0.1, password=123456, DBNAME=account, PORT=3306, NUM_HOSTS=1, PORT.1=3306},url = jdbc:mysql://127.0.0.1:3306/account, return newConn; //com.mysql.jdbc.JDBC4Connection@221af3c0 }
ConnectionImpl类: protected static Connection getInstance(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) { return (Connection) Util.handleNewInstance(JDBC_4_CONNECTION_CTOR, new Object[] { hostToConnectTo, Integer.valueOf(portToConnectTo), info, databaseToConnectTo, url }, null); }
public static final Object handleNewInstance(Constructor<?> ctor, Object[] args, ExceptionInterceptor exceptionInterceptor) { return ctor.newInstance(args); //public com.mysql.jdbc.JDBC4Connection ,args = [127.0.0.1, 3306, {HOST=127.0.0.1, user=root, HOST.1=127.0.0.1, password=123456, DBNAME=account, PORT=3306, NUM_HOSTS=1, PORT.1=3306}, account, jdbc:mysql://127.0.0.1:3306/account] }
JDBC4Connection类: public JDBC4Connection(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) throws SQLException { super(hostToConnectTo, portToConnectTo, info, databaseToConnectTo, url); }
public ConnectionImpl(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) { this.origHostToConnectTo = hostToConnectTo; //127.0.0.1 this.origPortToConnectTo = portToConnectTo; //3306 this.origDatabaseToConnectTo = databaseToConnectTo; //account this.port = portToConnectTo; //3306 this.database = databaseToConnectTo; //account this.myURL = url; //jdbc:mysql://127.0.0.1:3306/account this.user = info.getProperty(NonRegisteringDriver.USER_PROPERTY_KEY); //root this.password = info.getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY); //123456 this.props = info; //{HOST=127.0.0.1, user=root, HOST.1=127.0.0.1, password=123456, DBNAME=account, PORT=3306, NUM_HOSTS=1, PORT.1=3306} try { this.dbmd = getMetaData(false, false); initializeSafeStatementInterceptors(); createNewIO(false); unSafeStatementInterceptors(); } NonRegisteringDriver.trackConnection(this); }
public void createNewIO(boolean isForReconnect) throws SQLException { synchronized (getConnectionMutex()) { if (!getHighAvailability()) { connectOneTryOnly(isForReconnect, mergedProps); return; } } } private void connectOneTryOnly(boolean isForReconnect, Properties mergedProps) throws SQLException { try { coreConnect(mergedProps); return; } }
private void coreConnect(Properties mergedProps) throws SQLException, IOException { int newPort = 3306; String newHost = "localhost"; this.serverVariables.put("character_set_server", "utf8");//{character_set_server=utf8} this.io = new MysqlIO(newHost, newPort, mergedProps, getSocketFactoryClassName(), getProxy(), getSocketTimeout(), this.largeRowSizeThreshold.getValueAsInt()); //com.mysql.jdbc.MysqlIO@76a3e297,通过MYSQLIO执行IO操作。 this.io.doHandshake(this.user, this.password, this.database); }
public MysqlIO(String host, int port, Properties props, String socketFactoryClassName, MySQLConnection conn, int socketTimeout, int useBufferRowSizeThreshold) { this.connection = conn; //com.mysql.jdbc.JDBC4Connection@7d0587f1 try { this.mysqlConnection = this.socketFactory.connect(this.host, this.port, props); //返回Socket[addr=/127.0.0.1,port=3306,localport=59593] this.mysqlConnection = this.socketFactory.beforeHandshake(); //Socket[addr=/127.0.0.1,port=3306,localport=59593] } }
StandardSocketFactory类: public Socket connect(String hostname, int portNumber, Properties props) throws SocketException, IOException { if (props != null) { for (int i = 0; i < possibleAddresses.length; i++) { try { this.rawSocket = createSocket(props); configureSocket(this.rawSocket, props); //配置socket InetSocketAddress sockAddr = new InetSocketAddress(possibleAddresses[i], this.port); ///127.0.0.1:3306 this.rawSocket.connect(sockAddr, getRealTimeout(connectTimeout)); //连接数据库 break; } } resetLoginTimeCountdown(); return this.rawSocket; //Socket[addr=/127.0.0.1,port=3306,localport=59422] } } }
Socket类: public void connect(SocketAddress endpoint, int timeout) throws IOException { InetSocketAddress epoint = (InetSocketAddress) endpoint; InetAddress addr = epoint.getAddress (); int port = epoint.getPort(); checkAddress(addr, "connect"); if (!oldImpl) impl.connect(epoint, timeout); }
SocksSocketImpl类: super.connect(epoint, remainingMillis(deadlineMillis)); AbstractPlainSocketImpl类: connectToAddress(this.address, port, timeout); doConnect(address, port, timeout); ///127.0.0.1,3306,0 synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException { try { try { socketConnect(address, port, timeout); } } }
DualStackPlainSocketImpl类: connectResult = connect0(nativefd, address, port); //native方法
不设置 connection.setAutoCommit(false);是在PreparedStatement.executeUpdate();时候就加到数据库了。
不设置 connection.setAutoCommit(false);connection.rollback();会报错,com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Can't call rollback when autocommit=true
设置 connection.setAutoCommit(false);是在connection.commit();时候就加到数据库了。
设置 connection.setAutoCommit(false);connection.close();并不会提交数据,再次connection.commit();就会报错MySQLNonTransientConnectionException: No operations allowed after connection closed.
不设置 connection.setAutoCommit(false);是在PreparedStatement.executeUpdate();时候 stmt = com.mysql.jdbc.JDBC42PreparedStatement@f0f2775: insert into money(name,money) values ('JACK2',100.0) public int executeUpdate() throws SQLException { return Util.truncateAndConvertToInt(executeLargeUpdate()); } public long executeLargeUpdate() throws SQLException { return executeUpdateInternal(true, false); }
return executeUpdateInternal(this.parameterValues, this.parameterStreams, this.isStream, this.streamLengths, this.isNull, isBatch); //parameterValues = [[39, 74, 65, 67, 75, 50, 39], [49, 48, 48, 46, 48]] = 'JACK2',100.0 protected long executeUpdateInternal(byte[][] batchedParameterStrings, InputStream[] batchedParameterStreams, boolean[] batchedIsStream, int[] batchedStreamLengths, boolean[] batchedIsNull, boolean isReallyBatch) { synchronized (checkClosed().getConnectionMutex()) { MySQLConnection locallyScopedConn = this.connection; //com.mysql.jdbc.JDBC4Connection@345965f2 Buffer sendPacket = fillSendPacket(batchedParameterStrings, batchedParameterStreams, batchedIsStream, batchedStreamLengths); //batchedParameterStrings = [[39, 74, 65, 67, 75, 50, 39], [49, 48, 48, 46, 48]] = 'JACK2',100.0,返回3 insert.into.money(name,money).values.('JACK2',100.0) rs = executeInternal(-1, sendPacket, false, false, null, isReallyBatch); return this.updateCount; //1 } }
protected Buffer fillSendPacket(byte[][] batchedParameterStrings, InputStream[] batchedParameterStreams, boolean[] batchedIsStream, int[] batchedStreamLengths) { synchronized (checkClosed().getConnectionMutex()) { Buffer sendPacket = this.connection.getIO().getSharedSendPacket(); sendPacket.clear(); sendPacket.writeByte((byte) MysqlDefs.QUERY); //sendPacket插入QUERY=3, for (int i = 0; i < batchedParameterStrings.length; i++) { sendPacket.writeBytesNoNull(this.staticSqlStrings[i]); if (batchedIsStream[i]) { streamToBytes(sendPacket, batchedParameterStreams[i], true, batchedStreamLengths[i], useStreamLengths); } else { sendPacket.writeBytesNoNull(batchedParameterStrings[i]); } } sendPacket.writeBytesNoNull(this.staticSqlStrings[batchedParameterStrings.length]); return sendPacket; //3 insert.into.money(name,money).values.('JACK2',100.0) } }
protected ResultSetInternalMethods executeInternal(int maxRowsToRetrieve, Buffer sendPacket, boolean createStreamingResultSet, boolean queryIsSelectOnly, Field[] metadataFromCache, boolean isBatch) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { try { MySQLConnection locallyScopedConnection = this.connection; //com.mysql.jdbc.JDBC4Connection@345965f2 try { rs = locallyScopedConnection.execSQL(this, null, maxRowsToRetrieve, sendPacket, this.resultSetType, this.resultSetConcurrency, createStreamingResultSet, this.currentCatalog, metadataFromCache, isBatch); }
public ResultSetInternalMethods execSQL(StatementImpl callingStatement, String sql, int maxRows, Buffer packet, int resultSetType, int resultSetConcurrency, { return this.io.sqlQueryDirect(callingStatement, null, null, packet, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, cachedMetadata); //通过MYSQLIO执行IO操作。 }
Buffer resultPacket = sendCommand(MysqlDefs.QUERY, null, queryPacket, false, null, 0); //queryPacket = 3 insert.into.money(name,money).values.('JACK2',100.0) send(queryPacket, queryPacket.getPosition()); //queryPacket = 3 insert.into.money(name,money).values.('JACK2',100.0) this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, packetLen);//packetToSend = insert into money(name,money) values ('JACK2',100.0) this.mysqlOutput.flush(); //数据插入到数据库了,mysqlOutput = SET autocommit=1
connection.setAutoCommit(false); public void setAutoCommit(final boolean autoCommitFlag) throws SQLException { synchronized (getConnectionMutex()) { try { if (this.transactionsSupported) { this.autoCommit = autoCommitFlag; //false,不自动提交 if (needsSetOnServer) { execSQL(null, autoCommitFlag ? "SET autocommit=1" : "SET autocommit=0", -1, null, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY, false, this.database, null, false); } } } return; } }
public ResultSetInternalMethods execSQL(StatementImpl callingStatement, String sql, int maxRows, Buffer packet, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Field[] cachedMetadata, boolean isBatch) throws SQLException { synchronized (getConnectionMutex()) { try { if (packet == null) { return this.io.sqlQueryDirect(callingStatement, sql, encoding, null, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, cachedMetadata); //通过MYSQLIO执行IO操作。 } } } }
this.sendPacket.writeStringNoNull(query, characterEncoding, this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), this.connection); //query = SET autocommit=0 Buffer resultPacket = sendCommand(MysqlDefs.QUERY, null, queryPacket, false, null, 0); //queryPacket = SET autocommit=0 send(queryPacket, queryPacket.getPosition()); this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, packetLen); this.mysqlOutput.flush(); //SET autocommit=0执行flush操作。mysqlOutput = SET autocommit=1 */
insertTest(connection); public static void insertTest(Connection con) throws SQLException { PreparedStatement stmt = con.prepareStatement("insert into money(name,money) values (?,?)"); stmt.setString(1, "JACK2"); stmt.setDouble(2, 100.0); stmt.executeUpdate(); System.out.println("Data inserted successfully"); stmt.close(); }
public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException { return prepareStatement(sql, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY); } public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { synchronized (getConnectionMutex()) { String nativeSql = getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql) : sql; //insert into money(name,money) values (?,?) if (this.useServerPreparedStmts && canServerPrepare) { } else { pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false); } return pStmt; //com.mysql.jdbc.JDBC42PreparedStatement@f0f2775: insert into money(name,money) values (** NOT SPECIFIED **,** NOT SPECIFIED **) } }
public java.sql.PreparedStatement clientPrepareStatement(String sql, int resultSetType, int resultSetConcurrency, boolean processEscapeCodesIfNeeded) { String nativeSql = processEscapeCodesIfNeeded && getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql) : sql; //insert into money(name,money) values (?,?) if (getCachePreparedStatements()) { } else { pStmt = com.mysql.jdbc.PreparedStatement.getInstance(getMultiHostSafeProxy(), nativeSql, this.database); //返回com.mysql.jdbc.JDBC42PreparedStatement@f0f2775: insert into money(name,money) values (** NOT SPECIFIED **,** NOT SPECIFIED **) } pStmt.setResultSetType(resultSetType); pStmt.setResultSetConcurrency(resultSetConcurrency); return pStmt; }
protected static PreparedStatement getInstance(MySQLConnection conn, String sql, String catalog) throws SQLException { return (PreparedStatement) Util.handleNewInstance(JDBC_4_PSTMT_3_ARG_CTOR, new Object[] { conn, sql, catalog }, conn.getExceptionInterceptor()); //JDBC_4_PSTMT_3_ARG_CTOR = public com.mysql.jdbc.JDBC42PreparedStatement(com.mysql.jdbc.MySQLConnection, String, String) ,conn = JDBC4Connection,sql = insert into money(name,money) values (?,?),catalog = account, } public static final Object handleNewInstance(Constructor<?> ctor, Object[] args, ExceptionInterceptor exceptionInterceptor) throws SQLException { try { return ctor.newInstance(args); } } }
JDBC42PreparedStatement类: public JDBC42PreparedStatement(MySQLConnection conn, String sql, String catalog) throws SQLException { super(conn, sql, catalog); //conn= } public JDBC4PreparedStatement(MySQLConnection conn, String sql, String catalog) throws SQLException { super(conn, sql, catalog); } public PreparedStatement(MySQLConnection conn, String sql, String catalog) throws SQLException { super(conn, catalog); ////com.mysql.jdbc.JDBC4Connection@221af3c0,account this.originalSql = sql; //insert into money(name,money) values (?,?) this.dbmd = this.connection.getMetaData(); //JDBC4DatabaseMetaData }
public StatementImpl(MySQLConnection c, String catalog) throws SQLException { this.connection = c; //com.mysql.jdbc.JDBC4Connection@221af3c0 this.currentCatalog = catalog; //account if (!this.connection.getDontTrackOpenResources()) { this.connection.registerStatement(this); //this = JDBC42PreparedStatement } }
stmt.setString(1, "JACK2"); public void setString(int parameterIndex, String x) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (x == null) { } else { String parameterAsString = x; //JACK222,内容 byte[] parameterAsBytes = null; if (!this.isLoadDataQuery) { if (needsQuoted) { parameterAsBytes = StringUtils.getBytesWrapped(parameterAsString, '\'', '\'', this.charConverter, this.charEncoding, this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), getExceptionInterceptor()); //parameterAsBytes = 'JACK2' } else { } } setInternal(parameterIndex, parameterAsBytes); //设置第一个?为JACK222内容,parameterIndex = 1,parameterAsBytes = 'JACK2' this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.VARCHAR; //设置第一个?参数类型为VARCHAR } } }
protected final void setInternal(int paramIndex, byte[] val) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { this.isStream[paramIndex - 1 + parameterIndexOffset] = false; this.isNull[paramIndex - 1 + parameterIndexOffset] = false; this.parameterStreams[paramIndex - 1 + parameterIndexOffset] = null; this.parameterValues[paramIndex - 1 + parameterIndexOffset] = val; //parameterValues就是参数,设置第一个?为JACK222内容 } }
stmt.executeUpdate(); public int executeUpdate() throws SQLException { return Util.truncateAndConvertToInt(executeLargeUpdate()); } public long executeLargeUpdate() throws SQLException { return executeUpdateInternal(true, false); } protected long executeUpdateInternal(boolean clearBatchedGeneratedKeysAndWarnings, boolean isBatch) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { return executeUpdateInternal(this.parameterValues, this.parameterStreams, this.isStream, this.streamLengths, this.isNull, isBatch); } }
protected long executeUpdateInternal(byte[][] batchedParameterStrings, InputStream[] batchedParameterStreams, boolean[] batchedIsStream, int[] batchedStreamLengths, boolean[] batchedIsNull, boolean isReallyBatch) { synchronized (checkClosed().getConnectionMutex()) { MySQLConnection locallyScopedConn = this.connection; //com.mysql.jdbc.JDBC4Connection@221af3c0 Buffer sendPacket = fillSendPacket(batchedParameterStrings, batchedParameterStreams, batchedIsStream, batchedStreamLengths); //sendPacket = 3 insert.into.money(name,money).values.('JACK2',100.0) rs = executeInternal(-1, sendPacket, false, false, null, isReallyBatch); return this.updateCount; } }
protected ResultSetInternalMethods executeInternal(int maxRowsToRetrieve, Buffer sendPacket, boolean createStreamingResultSet, boolean queryIsSelectOnly, Field[] metadataFromCache, boolean isBatch) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { rs = locallyScopedConnection.execSQL(this, null, maxRowsToRetrieve, sendPacket, this.resultSetType, this.resultSetConcurrency, createStreamingResultSet, this.currentCatalog, metadataFromCache, isBatch); //sendPacket = 3 insert.into.money(name,money).values.('JACK2',100.0) return rs; } } }
public ResultSetInternalMethods execSQL(StatementImpl callingStatement, String sql, int maxRows, Buffer packet, int resultSetType, int resultSetConcurrency, { return this.io.sqlQueryDirect(callingStatement, null, null, packet, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, cachedMetadata); //通过MYSQLIO执行IO操作。 } Buffer resultPacket = sendCommand(MysqlDefs.QUERY, null, queryPacket, false, null, 0); //queryPacket = 3 insert.into.money(name,money).values.('JACK2',100.0) send(queryPacket, queryPacket.getPosition()); //queryPacket = 3 insert.into.money(name,money).values.('JACK2',100.0) this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, packetLen); //packetToSend = insert into money(name,money) values ('JACK2',100.0) this.mysqlOutput.flush(); //数据没有插入到数据库了。commit=true/false,代码执行是一样的,都flush出去了,只是服务器端没有执行。mysqlOutput = SET autocommit=0*/
stmt.close(); public void close() throws SQLException { realClose(true, true); }
protected void realClose(boolean calledExplicitly, boolean closeOpenResults) throws SQLException { MySQLConnection locallyScopedConn = this.connection; //com.mysql.jdbc.JDBC4Connection@221af3c0 synchronized (locallyScopedConn.getConnectionMutex()) { super.realClose(calledExplicitly, closeOpenResults); this.dbmd = null; //com.mysql.jdbc.JDBC4DatabaseMetaData里面有数据库信息和表信息 this.originalSql = null; //insert into money(name,money) values (?,?) this.staticSqlStrings = null; //insert into money(name,money) values (?,?) this.parameterValues = null; //'JACK2' ,100.0 this.parameterStreams = null; this.isStream = null; this.streamLengths = null; this.isNull = null; this.streamConvertBuf = null; this.parameterTypes = null; } }
protected void realClose(boolean calledExplicitly, boolean closeOpenResults) throws SQLException { MySQLConnection locallyScopedConn = this.connection; //com.mysql.jdbc.JDBC4Connection@221af3c0 if (!locallyScopedConn.getDontTrackOpenResources()) { locallyScopedConn.unregisterStatement(this); //移除JDBC42PreparedStatement } if (closeOpenResults) { if (this.results != null) { try { this.results.close(); } } closeAllOpenResults(); } this.isClosed = true; this.results = null; this.generatedKeysResults = null; this.connection = null; this.warningChain = null; this.openResults = null; this.batchedGeneratedKeys = null; this.localInfileInputStream = null; this.pingTarget = null; }
public void close() throws SQLException { realClose(true); } public void realClose(boolean calledExplicitly) throws SQLException { MySQLConnection locallyScopedConn = this.connection; //com.mysql.jdbc.JDBC4Connection@221af3c0 synchronized (locallyScopedConn.getConnectionMutex()) { try { if (this.useUsageAdvisor) { } finally { if (this.owningStatement != null && calledExplicitly) { this.owningStatement.removeOpenResultSet(this); } } } }
connection.commit(); public void commit() throws SQLException { synchronized (getConnectionMutex()) { try { if (this.autoCommit && !getRelaxAutoCommit()) { } else if (this.transactionsSupported) { execSQL(null, "commit", -1, null, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY, false, this.database, null, false); } } finally { this.needsPing = this.getReconnectAtTxEnd(); } } return; }
public ResultSetInternalMethods execSQL(StatementImpl callingStatement, String sql, int maxRows, Buffer packet, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Field[] cachedMetadata, boolean isBatch) throws SQLException { synchronized (getConnectionMutex()) { try { if (packet == null) { return this.io.sqlQueryDirect(callingStatement, sql, encoding, null, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, cachedMetadata); //io = com.mysql.jdbc.MysqlIO@709ba3fb, //通过MYSQLIO执行IO操作。 } } }
final ResultSetInternalMethods sqlQueryDirect(StatementImpl callingStatement, String query, String characterEncoding, Buffer queryPacket, int maxRows, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Field[] cachedMetadata) throws Exception { try { if (query != null) { this.sendPacket.writeByte((byte) MysqlDefs.QUERY); if (characterEncoding != null) { if (this.platformDbCharsetMatches) { } else { if (StringUtils.startsWithIgnoreCaseAndWs(query, "LOAD DATA")) { } else { this.sendPacket.writeStringNoNull(query, characterEncoding, this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), this.connection); } } } queryPacket = this.sendPacket; //commit } Buffer resultPacket = sendCommand(MysqlDefs.QUERY, null, queryPacket, false, null, 0); //通过socket发送commit ResultSetInternalMethods rs = readAllResults(callingStatement, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, resultPacket, false, -1L, cachedMetadata); } finally { this.statementExecutionDepth--; }
send(queryPacket, queryPacket.getPosition()); //queryPacket = commit this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, packetLen); this.mysqlOutput.flush(); //数据库有数据,mysqlOutput = commit into money(name,money) values ('JACK2',100.0)) */
connection.rollback(); public void rollback() throws SQLException { synchronized (getConnectionMutex()) { try { if (this.autoCommit && !getRelaxAutoCommit()) { } else if (this.transactionsSupported) { try { rollbackNoChecks(); } } } } } }
private void rollbackNoChecks() throws SQLException { execSQL(null, "rollback", -1, null, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY, false, this.database, null, false); } return this.io.sqlQueryDirect(callingStatement, sql, encoding, null, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, cachedMetadata); send(queryPacket, queryPacket.getPosition()); ///queryPacket = rollback this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, packetLen); this.mysqlOutput.flush(); //mysqlOutput = rollbacknto money(name,money) values ('JACK2',100.0)