上文solr dataimport源码主要实现的是数据读取功能
下面我们接着看数据连接的实现的源码:
private Connection getConnection() throws Exception { long currTime = System.currentTimeMillis(); if (currTime - connLastUsed > CONN_TIME_OUT) { synchronized ( this) { Connection tmpConn = factory.call(); closeConnection(); connLastUsed = System.currentTimeMillis(); return conn = tmpConn; } } else { connLastUsed = currTime; return conn; }
这里用到了synchronized关键字,使对 成员变量 conn访问 线程安全 }
其中factory 是一个Callable<Connection>类型的对象,是在初始化方法里面产生的
java的Callable接口定义如下
public interface Callable<V> { V call() throws Exception;
}
factory 初始化
public void init(Context context, Properties initProps) { // 其他代码略 factory = createConnectionFactory(context, initProps); }
接下来看createConnectionFactory(context, initProps) 代码如下
protected Callable<Connection> createConnectionFactory(final Context context,
final Properties initProps) { // final VariableResolver resolver = context.getVariableResolver(); resolveVariables(context, initProps); final String jndiName = initProps.getProperty(JNDI_NAME); final String url = initProps.getProperty(URL); final String driver = initProps.getProperty(DRIVER); if (url == null && jndiName == null) throw new DataImportHandlerException(SEVERE, "JDBC URL or JNDI name has to be specified"); if (driver != null) { try { DocBuilder.loadClass(driver, context.getSolrCore()); } catch (ClassNotFoundException e) { wrapAndThrow(SEVERE, e, "Could not load driver: " + driver); } } else { if(jndiName == null){ throw new DataImportHandlerException(SEVERE, "One of driver or jndiName must be specified in the data source"); } } String s = initProps.getProperty("maxRows"); if (s != null) { maxRows = Integer.parseInt(s); } return factory = new Callable<Connection>() { public Connection call() throws Exception { LOG.info("Creating a connection for entity " + context.getEntityAttribute(DataImporter.NAME) + " with URL: " + url); long start = System.currentTimeMillis(); Connection c = null; try { if(url != null){ c = DriverManager.getConnection(url, initProps); } else if(jndiName != null){ InitialContext ctx = new InitialContext(); Object jndival = ctx.lookup(jndiName); if (jndival instanceof javax.sql.DataSource) { javax.sql.DataSource dataSource = (javax.sql.DataSource) jndival; String user = (String) initProps.get("user"); String pass = (String) initProps.get("password"); if(user == null || user.trim().equals("")){ c = dataSource.getConnection(); } else { c = dataSource.getConnection(user, pass); } } else { throw new DataImportHandlerException(SEVERE, "the jndi name : '"+jndiName +"' is not a valid javax.sql.DataSource"); } } } catch (SQLException e) { // DriverManager does not allow you to use a driver which is not loaded through // the class loader of the class which is trying to make the connection. // This is a workaround for cases where the user puts the driver jar in the // solr.home/lib or solr.home/core/lib directories. Driver d = (Driver) DocBuilder.loadClass(driver, context.getSolrCore()).newInstance(); c = d.connect(url, initProps); } if (c != null) { if (Boolean.parseBoolean(initProps.getProperty("readOnly"))) { c.setReadOnly( true); // Add other sane defaults c.setAutoCommit( true); c.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); c.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT); } if (!Boolean.parseBoolean(initProps.getProperty("autoCommit"))) { c.setAutoCommit( false); } String transactionIsolation = initProps.getProperty("transactionIsolation"); if ("TRANSACTION_READ_UNCOMMITTED".equals(transactionIsolation)) { c.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); } else if ("TRANSACTION_READ_COMMITTED".equals(transactionIsolation)) { c.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); } else if ("TRANSACTION_REPEATABLE_READ".equals(transactionIsolation)) { c.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); } else if ("TRANSACTION_SERIALIZABLE".equals(transactionIsolation)) { c.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); } else if ("TRANSACTION_NONE".equals(transactionIsolation)) { c.setTransactionIsolation(Connection.TRANSACTION_NONE); } String holdability = initProps.getProperty("holdability"); if ("CLOSE_CURSORS_AT_COMMIT".equals(holdability)) { c.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT); } else if ("HOLD_CURSORS_OVER_COMMIT".equals(holdability)) { c.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT); } } LOG.info("Time taken for getConnection(): " + (System.currentTimeMillis() - start)); return c; } }; }
这里负责生成Connection对象