说明
本文主要是讲事务何时获取连接?何时归还连接?
框架:spring,hibernate,dbcp。
事务拦截器准备工作
准备执行service类的事务业务方法,执行之前,先被事务拦截器拦截。
调用栈
borrowObject:1059, GenericObjectPool (org.apache.commons.pool.impl) //从连接池获取连接
getConnection:106, PoolingDataSource (org.apache.commons.dbcp)
getConnection:1044, BasicDataSource (org.apache.commons.dbcp)
getConnection:26, DbcpSecretBasicDataSource (xxx.qrcode.common.monitor.dbcp)
getConnection:83, LocalDataSourceConnectionProvider (org.springframework.orm.hibernate3) //获取连接
openConnection:446, ConnectionManager (org.hibernate.jdbc)
getConnection:167, ConnectionManager (org.hibernate.jdbc)
connection:160, JDBCContext (org.hibernate.jdbc)
begin:81, JDBCTransaction (org.hibernate.transaction)
beginTransaction:1473, SessionImpl (org.hibernate.impl)
doBegin:556, HibernateTransactionManager (org.springframework.orm.hibernate3) //开始事务
getTransaction:372, AbstractPlatformTransactionManager (org.springframework.transaction.support) //获取事务
createTransactionIfNecessary:417, TransactionAspectSupport (org.springframework.transaction.interceptor)
invokeWithinTransaction:255, TransactionAspectSupport (org.springframework.transaction.interceptor)
invoke:94, TransactionInterceptor (org.springframework.transaction.interceptor) //事务拦截器
proceed:172, ReflectiveMethodInvocation (org.springframework.aop.framework)
invoke:91, ExposeInvocationInterceptor (org.springframework.aop.interceptor)
proceed:172, ReflectiveMethodInvocation (org.springframework.aop.framework)
intercept:631, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
merModifyNoAudit:-1, UrmtminfService$$EnhancerByCGLIB$$57be0f77 (xxx.qrcode.register.dbservice.impl)
merModifyNoAudit:517, QrcodeRegisterServer (xxx.qrcode.register.remoteserver.impl)
invokeMethod:-1, Wrapper20 (com.alibaba.dubbo.common.bytecode)
doInvoke:47, JavassistProxyFactory$1 (com.alibaba.dubbo.rpc.proxy.javassist)
invoke:76, AbstractProxyInvoker (com.alibaba.dubbo.rpc.proxy)
invoke:52, DelegateProviderMetaDataInvoker (com.alibaba.dubbo.config.invoker)
invoke:56, InvokerWrapper (com.alibaba.dubbo.rpc.protocol)
invoke:11, AppNameAppendFilter (com.xxx.log.rpc.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:62, ExceptionFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:42, TimeoutFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:60, ExecuteLimitFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:75, MonitorFilter (com.alibaba.dubbo.monitor.support)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:78, TraceFilter (com.alibaba.dubbo.rpc.protocol.dubbo.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:85, AccessLogExtFilter (xxx.qrcode.common.filter.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:82, CatTransaction (com.xxx.log.rpc.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:73, ContextFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:138, GenericFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:38, ClassLoaderFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:38, EchoFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
reply:104, DubboProtocol$1 (com.alibaba.dubbo.rpc.protocol.dubbo)
handleRequest:96, HeaderExchangeHandler (com.alibaba.dubbo.remoting.exchange.support.header)
received:173, HeaderExchangeHandler (com.alibaba.dubbo.remoting.exchange.support.header)
received:51, DecodeHandler (com.alibaba.dubbo.remoting.transport)
run:57, ChannelEventRunnable (com.alibaba.dubbo.remoting.transport.dispatcher)
runWorker:1145, ThreadPoolExecutor (java.util.concurrent)
run:615, ThreadPoolExecutor$Worker (java.util.concurrent)
run:745, Thread (java.lang)
是在事务开始的时候,就开始获取连接,而不是等到执行sql的时候才获取连接。
进入service
正式进入service类的业务方法的第一行代码,然后开始执行业务逻辑。
步骤
1.第一个sql
2.第二个sql
3.业务代码执行完成,进入事务拦截器
4.方法结束
执行sql的时候,所有sql都不需要再获取连接了,因为进入事务方法的时候被事务拦截器拦截的时候,就已经获取了连接,而且整个事务方法的所有sql都共用同一个连接。
事务拦截器收尾工作
调用栈
returnObject:1393, GenericObjectPool (org.apache.commons.pool.impl) //不是真的关闭,而是归还连接到连接池
close:90, PoolableConnection (org.apache.commons.dbcp)
close:191, PoolingDataSource$PoolGuardConnectionWrapper (org.apache.commons.dbcp) //关闭连接
doCloseConnection:341, DataSourceUtils (org.springframework.jdbc.datasource) //关闭连接
closeConnection:97, LocalDataSourceConnectionProvider (org.springframework.orm.hibernate3)
closeConnection:474, ConnectionManager (org.hibernate.jdbc) //关闭连接
cleanup:408, ConnectionManager (org.hibernate.jdbc)
close:347, ConnectionManager (org.hibernate.jdbc) //关闭连接
close:343, SessionImpl (org.hibernate.impl)
closeSession:802, SessionFactoryUtils (org.springframework.orm.hibernate3)
closeSessionOrRegisterDeferredClose:788, SessionFactoryUtils (org.springframework.orm.hibernate3) //关闭会话
doCleanupAfterCompletion:738, HibernateTransactionManager (org.springframework.orm.hibernate3)
cleanupAfterCompletion:1009, AbstractPlatformTransactionManager (org.springframework.transaction.support) //清理资源
processCommit:805, AbstractPlatformTransactionManager (org.springframework.transaction.support)
commit:724, AbstractPlatformTransactionManager (org.springframework.transaction.support)
commitTransactionAfterReturning:475, TransactionAspectSupport (org.springframework.transaction.interceptor) //提交事务
invokeWithinTransaction:270, TransactionAspectSupport (org.springframework.transaction.interceptor) //事务拦截器
invoke:94, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:172, ReflectiveMethodInvocation (org.springframework.aop.framework)
invoke:91, ExposeInvocationInterceptor (org.springframework.aop.interceptor)
proceed:172, ReflectiveMethodInvocation (org.springframework.aop.framework)
intercept:631, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
merModifyNoAudit:-1, UrmtminfService$$EnhancerByCGLIB$$57be0f77 (xxx.qrcode.register.dbservice.impl)
merModifyNoAudit:517, QrcodeRegisterServer (xxx.qrcode.register.remoteserver.impl)
invokeMethod:-1, Wrapper20 (com.alibaba.dubbo.common.bytecode)
doInvoke:47, JavassistProxyFactory$1 (com.alibaba.dubbo.rpc.proxy.javassist)
invoke:76, AbstractProxyInvoker (com.alibaba.dubbo.rpc.proxy)
invoke:52, DelegateProviderMetaDataInvoker (com.alibaba.dubbo.config.invoker)
invoke:56, InvokerWrapper (com.alibaba.dubbo.rpc.protocol)
invoke:11, AppNameAppendFilter (com.xxx.log.rpc.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:62, ExceptionFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:42, TimeoutFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:60, ExecuteLimitFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:75, MonitorFilter (com.alibaba.dubbo.monitor.support)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:78, TraceFilter (com.alibaba.dubbo.rpc.protocol.dubbo.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:85, AccessLogExtFilter (xxx.qrcode.common.filter.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:82, CatTransaction (com.xxx.log.rpc.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:73, ContextFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:138, GenericFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:38, ClassLoaderFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:38, EchoFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
reply:104, DubboProtocol$1 (com.alibaba.dubbo.rpc.protocol.dubbo)
handleRequest:96, HeaderExchangeHandler (com.alibaba.dubbo.remoting.exchange.support.header)
received:173, HeaderExchangeHandler (com.alibaba.dubbo.remoting.exchange.support.header)
received:51, DecodeHandler (com.alibaba.dubbo.remoting.transport)
run:57, ChannelEventRunnable (com.alibaba.dubbo.remoting.transport.dispatcher)
runWorker:1145, ThreadPoolExecutor (java.util.concurrent)
run:615, ThreadPoolExecutor$Worker (java.util.concurrent)
run:745, Thread (java.lang)
步骤
主要是释放资源,
1.关闭会话
关闭hibernate会话。
2.关闭连接
最终只是归还连接到连接池,并没有真的关闭。
归还连接到连接池
GenericObjectPool
public void returnObject(T obj) throws Exception {
try {
this.addObjectToPool(obj, true); //归还连接到连接池
} catch (Exception var7) {
if (this._factory != null) {
try {
this._factory.destroyObject(obj);
} catch (Exception var6) {
}
synchronized(this) {
--this._numActive;
}
this.allocate();
}
}
}
private void addObjectToPool(T obj, boolean decrementNumActive) throws Exception {
boolean success = true;
if (this._testOnReturn && !this._factory.validateObject(obj)) {
success = false;
} else {
this._factory.passivateObject(obj);
}
boolean shouldDestroy = !success;
boolean doAllocate = false;
synchronized(this) { //有锁
if (this.isClosed()) {
shouldDestroy = true;
} else if (this._maxIdle >= 0 && this._pool.size() >= this._maxIdle) {
shouldDestroy = true;
} else if (success) {
if (this._lifo) {
this._pool.addFirst(new ObjectTimestampPair(obj)); //归还连接到连接池,连接池其实就是一个连接对象集合
} else {
this._pool.addLast(new ObjectTimestampPair(obj));
}
if (decrementNumActive) {
--this._numActive;
}
doAllocate = true;
}
}
if (doAllocate) {
this.allocate();
}
if (shouldDestroy) {
try {
this._factory.destroyObject(obj);
} catch (Exception var10) {
}
if (decrementNumActive) {
synchronized(this) {
--this._numActive;
}
this.allocate();
}
}
}
总结
主要是通过源码的调用栈去看整个流程,一目了然,非常清晰。