MySQL连接管理
在调用SqlSessionFactory的openSession函数时,只是创建了一个DefaultSqlSession实例,并没有真正去连接MySQL:
1 |
|
只有当真正执行SQL语句时,比如query,才通过SimpleExecutor调用doQuery->prepareStatement进入父类BaseExecutor的getConnection,最终通过Transaction(JdbcTransaction)调用DataSource(PooledDataSource)的popConnection:
1 |
|
流程图如下:
这里需要注意的是,最终返回的是利用JAVA动态代理创建的实际连接的代理连接PooledConnection(具体实现原理见动态代理实现原理):
1 |
|
当调用实际连接的方法时,就会进入PooledConnection的invoke方法:
1 |
|
该方法会拦截实际连接的close方法,实际调用DataSource的pushConnection方法:
1 |
|
该方法判断如果空闲连接数小于上限则回收该连接(这里没有想明白为什么要重新建一个PooledConnection而不是直接复用原来的实例,希望有高手可以在留言里帮忙指点迷津)并唤醒等待获取连接的线程,否则关闭连接。 这里涉及到的主要类的UML图如下:
在JdbcTransaction中利用PooledDataSource的popConnection获取到连接后,会设置是否自动提交(Mysql默认是自动提交,但MyBatis默认是关闭自动提交)和事务隔离等级:
1 |
|