通过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)
Original: https://www.cnblogs.com/yaowen/p/12259962.html
Author: 哈哈呵h
Title: JDBC事务–自动提交
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/546178/
转载文章受原作者版权保护。转载请注明原作者出处!