首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

Mysql JDBC驱动源码分析(获取联接)二

2012-07-16 
Mysql JDBC驱动源码分析(获取连接)二setReadonly(true)?概念:从这一点设置的时间点开始到这个事务结束的过

Mysql JDBC驱动源码分析(获取连接)二

setReadonly(true)

?概念:从这一点设置的时间点开始到这个事务结束的过程中,其他事务所提交的数据,该事务将看不见!(查询中不会出现别人在时间点a之后提交的数据)

应用场合:

如果你一次执行单条查询语句,则没有必要启用事务支持,数据库默认支持SQL执行期间的读一致性;?

如果你一次执行多条查询语句,例如统计查询,报表查询,在这种场景下,多条查询SQL必须保证整体的读一致性,否则,在前条SQL查询之后,后条SQL查询之前,数据被其他用户改变,则该次整体的统计查询将会出现读数据不一致的状态,此时,应该启用事务支持。

【注意是一次执行多次查询来统计某些信息,这时为了保证数据整体的一致性,要用只读事务】

怎样设置:

对于只读查询,可以指定事务类型为readonly,即只读事务。

由于只读事务不存在数据的修改,因此数据库将会为只读事务提供一些优化手段,例如Oracle对于只读事务,不启动回滚段,不记录回滚log。

?

?

当驱动加载完毕后,接下来就是怎样去获取一个连接

?

Drivermanager.getConnection(url,name,password)

?跟踪代码执行到以下一步

?

 private static Connection getConnection(String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {java.util.Vector drivers = null;        /* * When callerCl is null, we should check the application's * (which is invoking this class indirectly) * classloader, so that the JDBC driver class outside rt.jar * can be loaded from here. */synchronized(DriverManager.class) {   // synchronize loading of the correct classloader.  if(callerCL == null) {      callerCL = Thread.currentThread().getContextClassLoader();   }    }  if(url == null) {    throw new SQLException("The url cannot be null", "08001");}    println("DriverManager.getConnection("" + url + "")");    if (!initialized) {    initialize();}synchronized (DriverManager.class){             // use the readcopy of drivers    drivers = readDrivers;          }// Walk through the loaded drivers attempting to make a connection.// Remember the first exception that gets raised so we can reraise it.SQLException reason = null;for (int i = 0; i < drivers.size(); i++) {    DriverInfo di = (DriverInfo)drivers.elementAt(i);          // If the caller does not have permission to load the driver then     // skip it.    if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) {println("    skipping: " + di);continue;    }    try {println("    trying " + di);                //在注册的驱动中得到相应的连接Connection result = di.driver.connect(url, info);if (result != null) {    // Success!    println("getConnection returning " + di);    return (result);}    } catch (SQLException ex) {if (reason == null) {    reason = ex;}    }}    // if we got here nobody could connect.if (reason != null)    {    println("getConnection failed: " + reason);    throw reason;}    println("getConnection: no suitable driver found for "+ url);throw new SQLException("No suitable driver found for "+ url, "08001");    }

?进入com.mysql.jdbc.Driver下connect(url,info)方法NonRegisteringDriver

?

?

public java.sql.Connection connect(String url, Properties info)throws SQLException {if (url != null) {if (StringUtils.startsWithIgnoreCase(url, LOADBALANCE_URL_PREFIX)) {//负载均衡的配置return connectLoadBalanced(url, info);} else if (StringUtils.startsWithIgnoreCase(url,REPLICATION_URL_PREFIX)) {//复制return connectReplicationConnection(url, info);}}Properties props = null;if ((props = parseURL(url, info)) == null) {return null;}if (!"1".equals(props.getProperty(NUM_HOSTS_PROPERTY_KEY))) {return connectFailover(url, info);}try {//初始化链接Connection newConn = com.mysql.jdbc.ConnectionImpl.getInstance(host(props), port(props), props, database(props), url);return newConn;} catch (SQLException sqlEx) {// Don't wrap SQLExceptions, throw// them un-changed.throw sqlEx;} catch (Exception ex) {SQLException sqlEx = SQLError.createSQLException(Messages.getString("NonRegisteringDriver.17") //$NON-NLS-1$+ ex.toString()+ Messages.getString("NonRegisteringDriver.18"), //$NON-NLS-1$SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, null);sqlEx.initCause(ex);throw sqlEx;}}
?

?对com.mysql.jdbc.JDBC4Connection的初始化

?

protected static Connection getInstance(String hostToConnectTo,int portToConnectTo, Properties info, String databaseToConnectTo,String url) throws SQLException {if (!Util.isJdbc4()) {return new ConnectionImpl(hostToConnectTo, portToConnectTo, info,databaseToConnectTo, url);}               //初始化return (Connection) Util.handleNewInstance(JDBC_4_CONNECTION_CTOR,new Object[] {hostToConnectTo, Integer.valueOf(portToConnectTo), info,databaseToConnectTo, url }, null);}

?进入Jdbc4Connection的代码跟踪

?

?

protected ConnectionImpl(String hostToConnectTo, int portToConnectTo, Properties info,String databaseToConnectTo, String url)throws SQLException {this.charsetToNumBytesMap = new HashMap();this.connectionCreationTimeMillis = System.currentTimeMillis();this.pointOfOrigin = new Throwable();      if (databaseToConnectTo == null) {databaseToConnectTo = "";}// Stash away for later, used to clone this connection for Statement.cancel// and Statement.setQueryTimeout().//this.origHostToConnectTo = hostToConnectTo;this.origPortToConnectTo = portToConnectTo;this.origDatabaseToConnectTo = databaseToConnectTo;try {Blob.class.getMethod("truncate", new Class[] {Long.TYPE});this.isRunningOnJDK13 = false;} catch (NoSuchMethodException nsme) {this.isRunningOnJDK13 = true;}this.sessionCalendar = new GregorianCalendar();this.utcCalendar = new GregorianCalendar();this.utcCalendar.setTimeZone(TimeZone.getTimeZone("GMT"));this.log = LogFactory.getLogger(getLogger(), LOGGER_INSTANCE_NAME, getExceptionInterceptor());// We store this per-connection, due to static synchronization// issues in Java's built-in TimeZone class...this.defaultTimeZone = Util.getDefaultTimeZone();if ("GMT".equalsIgnoreCase(this.defaultTimeZone.getID())) {this.isClientTzUTC = true;} else {this.isClientTzUTC = false;}this.openStatements = new HashMap();if (NonRegisteringDriver.isHostPropertiesList(hostToConnectTo)) {Properties hostSpecificProps = NonRegisteringDriver.expandHostKeyValues(hostToConnectTo);Enumeration<?> propertyNames = hostSpecificProps.propertyNames();while (propertyNames.hasMoreElements()) {String propertyName = propertyNames.nextElement().toString();String propertyValue = hostSpecificProps.getProperty(propertyName);info.setProperty(propertyName, propertyValue);}} else {if (hostToConnectTo == null) {this.host = "localhost";this.hostPortPair = this.host + ":" + portToConnectTo;} else {this.host = hostToConnectTo;if (hostToConnectTo.indexOf(":") == -1) {this.hostPortPair = this.host + ":" + portToConnectTo;} else {this.hostPortPair = this.host;}}}this.port = portToConnectTo;this.database = databaseToConnectTo;this.myURL = url;this.user = info.getProperty(NonRegisteringDriver.USER_PROPERTY_KEY);this.password = info.getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY);if ((this.user == null) || this.user.equals("")) {this.user = "";}if (this.password == null) {this.password = "";}this.props = info;initializeDriverProperties(info);try {   //获取数据库的信息this.dbmd = getMetaData(false, false);initializeSafeStatementInterceptors();                        //======================================创建远程IO连接createNewIO(false);unSafeStatementInterceptors();} catch (SQLException ex) {cleanup(ex);// don't clobber SQL exceptionsthrow ex;} catch (Exception ex) {cleanup(ex);StringBuffer mesg = new StringBuffer(128);if (!getParanoid()) {mesg.append("Cannot connect to MySQL server on ");mesg.append(this.host);mesg.append(":");mesg.append(this.port);mesg.append(".\n\n");mesg.append("Make sure that there is a MySQL server ");mesg.append("running on the machine/port you are trying ");mesg.append("to connect to and that the machine this software is "+ "running on ");mesg.append("is able to connect to this host/port "+ "(i.e. not firewalled). ");mesg.append("Also make sure that the server has not been started "+ "with the --skip-networking ");mesg.append("flag.\n\n");} else {mesg.append("Unable to connect to database.");}SQLException sqlEx = SQLError.createSQLException(mesg.toString(),SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE, getExceptionInterceptor());sqlEx.initCause(ex);throw sqlEx;}}
?

?

?

?

?

?

热点排行