您的位置:首页 > 运维架构 > Linux

Linux学习笔记之 RAID介绍,及centos6上软RAID的实现

2015-09-01 21:01 671 查看
本文主要对SSh2+OpenSessionInView和Spring声明式的事务,用最常见的配置做一些源代码的分析。第一次发帖,有错的地方,请指教

首先我们贴出Web.xml的配置。

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


Spring声明式事务的配置。

<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<tx:advice id="advice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" read-only="true" />
<tx:method name="save*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>

<aop:config proxy-target-class="false">
<aop:pointcut  expression="execution(* cn.service.impl.*.*(..))"
id="pointcut" />
<aop:advisor advice-ref="advice" pointcut-ref="pointcut" />
</aop:config>


贴上OpenSessionInView的源码
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
//获取SessionFactory,就是WebApplicationContext.getBean(getSessionFactoryBeanName(), SessionFactory.class);
SessionFactory sessionFactory = lookupSessionFactory(request);
boolean participate = false;
//是否是单Session模式
if (isSingleSession()) {
// 看看当前线程是否有绑定的资源。一般请求过来是没有的
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
// Do not modify the Session: just set the participate flag.
participate = true;
}
else {
//打开一个Session,在下面会讲到如何获取的Session的
logger.debug("Opening single Hibernate Session in OpenSessionInViewFilter");
Session session = getSession(sessionFactory);
//把获取的Session绑定到当前线程中。即ThreadLocal<Map<Object,Object>>
//这里Map的key是sessionFactory,value是SessionHolder,而真正的Session又是放在SessionHolder里面的一个同步的Map中。kew是一个默认的Object。value才是真正的Session
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}
}
else {
// 这是延期关闭模式,本文不做讨论
if (SessionFactoryUtils.isDeferredCloseActive(sessionFactory)) {
// Do not modify deferred close: just set the participate flag.
participate = true;
}
else {
SessionFactoryUtils.initDeferredClose(sessionFactory);
}
}

try {
//放行。。执行action-->service-->dao
filterChain.doFilter(request, response);
}

finally {
//如果上文打开了SESSION
if (!participate) {
//是单session模式
if (isSingleSession()) {
// 从当前线程移除资源
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
logger.debug("Closing single Hibernate Session in OpenSessionInViewFilter");
//关闭Session
closeSession(sessionHolder.getSession(), sessionFactory);
}
else {
// deferred close mode
SessionFactoryUtils.processDeferredClose(sessionFactory);
}
}
}
}


OpenSessionInView#getSession(sessionFactory)源码

protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
//使用SessionFactoryUtils获取一个Session。第二参数true,代表允许创建新的Session。下面会详细讲解怎么获取Session
//一般这里都是打开一个Session
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
FlushMode flushMode = getFlushMode();
//将FlushMode模式改成MANUAL值
if (flushMode != null) {
session.setFlushMode(flushMode);
}
return session;
}


SessionFactoryUtils.doGetSession()获取Session最核心的一个源码

//这里分两个部分。一是开启了事务。二是没有开启事务。
//或者说是一个请求的第一次调用和第2次以上的调用两种模式
//如果是第一次调用过来的没有事务的时候,则打开一个Session,然后返回出去
//如果是第二次以上调用有事务的时候。则是直接返回一个Session
private static Session doGetSession(
SessionFactory sessionFactory, Interceptor entityInterceptor,
SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)
throws HibernateException, IllegalStateException {
//如果是有事务的 则是第二次以上调用的 则执行以下if条件
Assert.notNull(sessionFactory, "No SessionFactory specified");
//从当前线程中获取SessionHolder
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
//如果sessionHolder不null。并且有Session
if (sessionHolder != null && !sessionHolder.isEmpty()) {
// pre-bound Hibernate Session
Session session = null;
//如果开启了事务 并且 sessionHolder中只有一个Session或没有Session
if (TransactionSynchronizationManager.isSynchronizationActive() &&
sessionHolder.doesNotHoldNonDefaultSession()) {
// Spring transaction management is active ->
// register pre-bound Session with it for transactional flushing.
//从SessionHolder中获取检查后的Session。这里其实是检查session有没关闭
session = sessionHolder.getValidatedSession();
//session不等于空 并且 没有开启事务
if (session != null && !sessionHolder.isSynchronizedWithTransaction()) {
logger.debug("Registering Spring transaction synchronization for existing Hibernate Session");
//注册一个SpringSessionSynchronization对象到当前线程
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false));
//设置同步事务开启
sessionHolder.setSynchronizedWithTransaction(true);
// Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
// with FlushMode.MANUAL, which needs to allow flushing within the transaction.
//获取session的提交模式
FlushMode flushMode = session.getFlushMode();
//如果提交模式小于COMMIT 并且当前线程的事务不是只读的
if (flushMode.lessThan(FlushMode.COMMIT) &&
!TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
//将提交模式设置成AUTO
session.setFlushMode(FlushMode.AUTO);
//将flushMode设置成旧的提交模式
sessionHolder.setPreviousFlushMode(flushMode);
}
}
}
else {
// 没有Spring事务管理活动。则是着获取Jta事务。这里不是我们的重点。不谈先
session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator);
}
//返回session
if (session != null) {
return session;
}
}

//		-- 没有事务的时候 一个请求第一次的调用--
//打开Session
logger.debug("Opening Hibernate Session");
Session session = (entityInterceptor != null ?
sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession());

// Use same Session for further Hibernate actions within the transaction.
// 一般这if不会被执行。
//如果当前线程的事务是活动的
if (TransactionSynchronizationManager.isSynchronizationActive()) {
// We're within a Spring-managed transaction, possibly from JtaTransactionManager.
logger.debug("Registering Spring transaction synchronization for new Hibernate Session");
SessionHolder holderToUse = sessionHolder;
//如果当前的SessionHolder是空的
if (holderToUse == null) {
//实例化一个SessionHolder
holderToUse = new SessionHolder(session);
}
else {
//增加一个Session到SessionHodler中。
holderToUse.addSession(session);
}
//如果当前线程事务的制度的
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
//将FluashMode设置MANUAL。
session.setFlushMode(FlushMode.MANUAL);
}
//注册一个SpringSessionSynchronization对象到当前线程中
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true));
//设置线程同步事务开启
holderToUse.setSynchronizedWithTransaction(true);
//这里比较是开上面是否实例化了SessionHolder。如果是则将SessionHolder绑定到当前线程中
if (holderToUse != sessionHolder) {
TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse);
}
}
else {
// No Spring transaction management active -> try JTA transaction synchronization.
registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder);
}

// 如果是不允许创建Session 并且 没有开启事务。则抛出异常。因为没有找到Session又不能创建新的。。
if (!allowCreate && !isSessionTransactional(session, sessionFactory)) {
closeSession(session);
throw new IllegalStateException("No Hibernate Session bound to thread, " +
"and configuration does not allow creation of non-transactional one here");
}

return session;
}


接下来就是执行对应的Action
public UserAction extends BaseAction{
private User user;
//省略getset方法
public String addUser(){
//这里面getUserService()方法就是获得Spring的代理类,
//这里使用JDK的动态代理在 <aop:config proxy-target-class="false"> 默认就是false
//调用这个类的方法之前要经过AOP拦截。下面我们来分析拦截的过程。
this.getServiceFacade().getUserService().addUser(user);
}
}

生产的代理类看不见源码,直接从JdkDynamicAopProxy类来。。
JdkDynamicAopProxy#invoke 源码
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation = null;
Object oldProxy = null;
boolean setProxyContext = false;
//获取目标源的包装对象   targetSource包含目标Service对象
TargetSource targetSource = this.advised.targetSource;
Class targetClass = null;
Object target = null;

try {
/如果目标类没有重载equals方法 && 目前正在调用目标类的equals方法,那直接调本类重载方法,
//这样就不需要再往下走,不需要再开启事务等等多余的操作以至于浪费性能了,下面的几个IF都是做类似的事
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}

Object retVal = null;
//如果可以暴露代理对象,即配置<aop:config expose-proxy="true">这个
//则将代理对象放入AOP上下文中
//这样方便在一个Service方法中。调用另一个有事务的方法时。也能起到配置事务的作用。。 调用:((UserService)AopContext.currentProxy()).deleteUser();
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}

// May be null. Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
//获取目标对象
target = targetSource.getTarget();
if (target != null) {
//获取目标对象的class
targetClass = target.getClass();
}

// Get the interception chain for this method.
//根据方法和目标对象的class属性。获取对应的拦截器。
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
//如果拦截器为空。
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
直接执行目标方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
else {
// We need to create a method invocation...
//实例化一个专门执行拦截器的对象来执行拦截器
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
//进行递归的拦截
retVal = invocation.proceed();
}

// Massage return value if necessary.
// 调用的返回结果目标类对象本身,就把它替换成代理类对象
if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
return retVal;
}
//释放资源操作,其实主要是在Aop上下文清除代理对象
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);dProxy);
}
}
}

ReflectiveMethodInvocation#proceed 源码
public Object proceed() throws Throwable {
//	We start with an index of -1 and increment early.
//如果没有拦截器则调用目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
//获取拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//拦截器是InterceptorAndDynamicMethodMatcher类型
//Spring事务拦截器TransactionInterceptor是MethodInterceptor实现类
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
//方法匹配失败,跳过,继续递归
return proceed();
}
}
else {

// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
// 调用事务拦截器等。。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}


按照我们的配置只有两个拦截器。1是ExposeInvocationInterceptor 2是事务拦截器TransactionInterceptor。ExposeInvocationInterceptor拦截器只是比较简单,只是拦截器放入ThreadLocal中。我们继续讨论最核心的事务拦截器

TransactionInterceptor#invoke 源代码
public Object invoke(final MethodInvocation invocation) throws Throwable {
// Work out the target class: may be <code>null</code>.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
//获取目标对象的class
Class targetClass = (invocation.getThis() != null ? invocation.getThis().getClass() : null);

// 获取事务定义的属性。例如<tx:method name="add*" propagation="REQUIRED" /> 和数据库隔离级别
final TransactionAttribute txAttr =
getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);
//获取事务管理对象。这里是HibernateTransactionManager
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
//获取方法的全限定名
final String joinpointIdentification = methodIdentification(invocation.getMethod());
//如果配置了事务 或者 事务管理者不是CallbackPreferringPlatformTransactionManager
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
//获取事务信息对象,然后将它邦定到ThreadLocal中,它包含了事务定义和事务的状态。这个TransactionInfo是TransactionAspectSupport的一个内部类
//createTransactionIfNecessary方法在父类TransactionAspectSupport中定义的。下面会细说
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
//继续递归拦截器。一般到这里都是执行我们的Service方法了
retVal = invocation.proceed();
}
catch (Throwable ex) {
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
//从当前线程中清除事务信息对象
cleanupTransactionInfo(txInfo);
}
//提交事务,清除ThreadLocal中保存的一些事务资源。
//如果是filter-action-service-dao的话。session不会关闭。只//会关闭connection
//	如果是直接从service调起的话。session会在事务提交后关闭。具体怎么关闭下面会详细说
commitTransactionAfterReturning(txInfo);
return retVal;
}

else {
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
//回调式事务。应该是可以由此接口的具体实现来决定事务的控//制。。具体我还没了解过。
try {
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
new TransactionCallback<Object>() {
public Object doInTransaction(TransactionStatus status) {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
try {
return invocation.proceed();
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
return new ThrowableHolder(ex);
}
}
finally {
cleanupTransactionInfo(txInfo);
}
}
});

// Check result: It might indicate a Throwable to rethrow.
if (result instanceof ThrowableHolder) {
throw ((ThrowableHolder) result).getThrowable();
}
else {
return result;
}
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
}
}


TransactionAspectSupport#createTransactionIfNecessary() 源代码
protected TransactionInfo createTransactionIfNecessary(
PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {

// 如果事务没有名字。则使用方面名做为事务的名字。将txAttr进行包装下
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}

TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
//这里调用事务管理器获得一个事务状态对象,这里会涉及真正的事务处理了。
//getTransaction()是事务模板管理器的方法。
status = tm.getTransaction(txAttr);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
//根据事务定义和状态,创建一个事务信息对象。并将自己绑定到当前线程中。
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}


AbstractPlatformTransactionManager#getTransaction() 源代码
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
//获取一个事务对象。这里调用了HibernateTransactionManager事务管理器的方法获取事务对象
Object transaction = doGetTransaction();

// Cache debug flag to avoid repeated checks.
boolean debugEnabled = logger.isDebugEnabled();
//如果没有定义事务属性。则使用默认的事务属性
if (definition == null) {
// Use defaults if no transaction definition given.
definition = new DefaultTransactionDefinition();
}
//如果已存在了事务对象
if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
return handleExistingTransaction(definition, transaction, debugEnabled);
}

// Check definition settings for new transaction.
//检查事务超时时间是否合法。不<-1
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
}

//如果事务传播特性配置的是mandatory,当前没有事务存在,抛出异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
//如果事务传播特性为required、required_new或nested
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
}
try {
//不激活和当前线程绑定的事务,因为事务传播特性配置要求创建新的事务
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
//创建一个事务状态
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
//创建事务的调用,具体实现由具体的事务处理器提供
doBegin(transaction, definition);
//准备初始化和同步事务状态
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException ex) {
resume(null, suspendedResources);
throw ex;
}
catch (Error err) {
resume(null, suspendedResources);
throw err;
}
}
else {
// Create "empty" transaction: no actual transaction, but potentially synchronization.
//创建空事务,针对supported类型的事务传播特性,激活和当前线程绑定的事务
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
//准备事务状态
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
}
}


HibernateTransactionManager#doGetTransaction() 源代码
protected Object doGetTransaction() {
//实例化一个HibernateTransactionObject对象。这个类是HibernateTransactionManager的内部类
HibernateTransactionObject txObject = new HibernateTransactionObject();
//设置是否是内嵌的事务
txObject.setSavepointAllowed(isNestedTransactionAllowed());
//从当前线程中获取SessionHolder。如果是filter-action-service的方式这里能获取到,如果直接
//从service调用则sessionHolder== null
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
if (sessionHolder != null) {
if (logger.isDebugEnabled()) {
logger.debug("Found thread-bound Session [" +
SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction");
}
//把SessionHolder放入HibernateTransactionObject对象。并且标志此session是旧的session
txObject.setSessionHolder(sessionHolder);
}
//如果当前Hibernate事务处理器有被管理的Hibernate Session
else if (this.hibernateManagedSession) {
try {
//获取当前的Hibernate Session
Session session = getSessionFactory().getCurrentSession();
if (logger.isDebugEnabled()) {
logger.debug("Found Hibernate-managed Session [" +
SessionFactoryUtils.toString(session) + "] for Spring-managed transaction");
}
//设置Hibernate事务对象已经存在指定的Session
txObject.setExistingSession(session);
}
catch (HibernateException ex) {
throw new DataAccessResourceFailureException(
"Could not obtain Hibernate-managed Session for Spring-managed transaction", ex);
}
}
//如果获取到的数据源不为null
if (getDataSource() != null) {
/将获取到的数据源和当前线程绑定
ConnectionHolder conHolder = (ConnectionHolder)
TransactionSynchronizationManager.getResource(getDataSource());
txObject.setConnectionHolder(conHolder);
}

return txObject;
}


HibernateTransactionManager#doBegin() 源代码
protected void doBegin(Object transaction, TransactionDefinition definition) {
//获取事务对象
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
//如果事务对象有ConnectionHolder,且事务对象的数据库连接不是事务同步的
if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
throw new IllegalTransactionStateException(
"Pre-bound JDBC Connection found! HibernateTransactionManager does not support " +
"running within DataSourceTransactionManager if told to manage the DataSource itself. " +
"It is recommended to use a single HibernateTransactionManager for all transactions " +
"on a single DataSource, no matter whether Hibernate or JDBC access.");
}

Session session = null;

try {
//如果事务对象没有SessionHolder 或者SessionHolder中的session是同步事务的。
if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
//获取Hibernate事务处理器中的实体拦截器
Interceptor entityInterceptor = getEntityInterceptor();
//获取Hibernate Session,如果实体拦截器不为null,则打开指定
//实体拦截器的Session,如果实体拦截器为null,则打开新Session
Session newSession = (entityInterceptor != null ?
getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());
if (logger.isDebugEnabled()) {
logger.debug("Opened new Session [" + SessionFactoryUtils.toString(newSession) +
"] for Hibernate transaction");
}
//设置session到事务对象中。并标记次session对象是新的session。
txObject.setSession(newSession);
}
//获取SessionHolder中已有的Hibernate Session
session = txObject.getSessionHolder().getSession();
//允许为JDBC连接改变事务设置
if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
// We're allowed to change the transaction settings of the JDBC Connection.
if (logger.isDebugEnabled()) {
logger.debug(
"Preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]");
}
//获取Session连接
Connection con = session.connection();
//获取事务的隔离级别
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
//设置事务对象的事务隔离级别
txObject.setPreviousIsolationLevel(previousIsolationLevel);
}
else {
// Not allowed to change the transaction settings of the JDBC Connection.
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
// We should set a specific isolation level but are not allowed to...
throw new InvalidIsolationLevelException(
"HibernateTransactionManager is not allowed to support custom isolation levels: " +
"make sure that its 'prepareConnection' flag is on (the default) and that the " +
"Hibernate connection release mode is set to 'on_close' (SpringTransactionFactory's default). " +
"Make sure that your LocalSessionFactoryBean actually uses SpringTransactionFactory: Your " +
"Hibernate properties should *not* include a 'hibernate.transaction.factory_class' property!");
}
if (logger.isDebugEnabled()) {
logger.debug(
"Not preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]");
}
}
//如果事务是只读,且事务对象是新的Hibernate Session
if (definition.isReadOnly() && txObject.isNewSession()) {
// Just set to NEVER in case of a new Session for this transaction.
session.setFlushMode(FlushMode.MANUAL);
}
//如果事务不是只读的 并且事务对象不是新Hibernate Session
if (!definition.isReadOnly() && !txObject.isNewSession()) {
// We need AUTO or COMMIT for a non-read-only transaction.
获取flushMode模式
FlushMode flushMode = session.getFlushMode();
//如果flushMode小于COMMIT
if (flushMode.lessThan(FlushMode.COMMIT)) {
//设置成AUTO
session.setFlushMode(FlushMode.AUTO);
//设置旧的fulshMode到事务对象中
txObject.getSessionHolder().setPreviousFlushMode(flushMode);
}
}

Transaction hibTx;

// Register transaction timeout.
//获取事务超时时长
int timeout = determineTimeout(definition);
//如果事务配置的超时时长不是事务默认超时时长
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
// Use Hibernate's own transaction timeout mechanism on Hibernate 3.1+
//获取Hibernate Session事务
hibTx = session.getTransaction();
//设置事务超长时间
hibTx.setTimeout(timeout);
//开始事务
hibTx.begin();
}
else {
// Open a plain Hibernate transaction without specified timeout.
//开始事务
hibTx = session.beginTransaction();
}

// Add the Hibernate transaction to the session holder.
//将事务设置到事务对象的SessionHolder中。
txObject.getSessionHolder().setTransaction(hibTx);
//如果数据源不为null,即设置了数据源
// Register the Hibernate Session's JDBC Connection for the DataSource, if set.
if (getDataSource() != null) {
//使用Hibernate Session打开数据库连接
Connection con = session.connection();
//创建ConnectionHolder
ConnectionHolder conHolder = new ConnectionHolder(con);
//设置超时时长
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
conHolder.setTimeoutInSeconds(timeout);
}
if (logger.isDebugEnabled()) {
logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]");
}
//将ConnectionHolder绑定到当前线程中
TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
//把connectionHolder放入事务对象中
txObject.setConnectionHolder(conHolder);
}

//如果事务对象是新的sessionHolder。则将它邦到当前线程中。(从Service层调用)在此绑定
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
}
//设置同步事务状态开启
txObject.getSessionHolder().setSynchronizedWithTransaction(true);
}

catch (Exception ex) {
if (txObject.isNewSession()) {
try {
//如果session开启了事务,则进行回滚
if (session.getTransaction().isActive()) {
session.getTransaction().rollback();
}
}
catch (Throwable ex2) {
logger.debug("Could not rollback Session after failed transaction begin", ex);
}
finally {
//关闭session
SessionFactoryUtils.closeSession(session);
}
}
throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);
}
}


AbstractPlatformTransactionManager#prepareSynchronization 源代码
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
//如果是新同步事务,这些线程同步事务都是在TransactionSynchronizationManager管理
if (status.isNewSynchronization()) {
//将当前线程的同步事务激活
TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
//设置当线程的数据库隔离状态
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
(definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) ?
definition.getIsolationLevel() : null);
//设置事务当前线程的只读状态
TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
//设置当前事务的名称到ThreadLocal
TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
//初始化当前线程对象集合  -- 这是是new LinkedList<TransactionSynchronization>()
TransactionSynchronizationManager.initSynchronization();
}
}


下面是 提交事务的代码分析
AbstractPlatformTransactionManager#commit
public final void commit(TransactionStatus status) throws TransactionException {
//如果事务已提交。则抛出异常
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}

DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
//如果事务执行状态时回滚
if (defStatus.isLocalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
//处理事务回滚
processRollback(defStatus);
return;
}
//如果事务没有被标记为回滚时提交,且事务状态时全局回滚
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
//回滚处理
processRollback(defStatus);
// Throw UnexpectedRollbackException only at outermost transaction boundary
// or if explicitly asked to.
//如果事务状态时新事务,或者在全局回滚时失败
if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
throw new UnexpectedRollbackException(
"Transaction rolled back because it has been marked as rollback-only");
}
return;
}
//处理提交
processCommit(defStatus);
}


AbstractPlatformTransactionManager#processCommit() 源代码
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;
try {
//事务提交的准备工作,这里是HibernateTransactionManager实现
prepareForCommit(status);
triggerBeforeCommit(status);
triggerBeforeCompletion(status);
beforeCompletionInvoked = true;
boolean globalRollbackOnly = false;
//如果事务状态是新事务,或者全局回滚失败
if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
globalRollbackOnly = status.isGlobalRollbackOnly();
}
//嵌套事务处理
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
//释放挂起事务保存点
status.releaseHeldSavepoint();
}
//如果当前事务是新事务
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction commit");
}
//调用hibernateTrancastionManager的doCommit方法。进行真正的提交事务
//而在方法中只是这样操作:status.getTransaction().getSessionHolder().getTransaction().commit();
doCommit(status);
}
// Throw UnexpectedRollbackException if we have a global rollback-only
// marker but still didn't get a corresponding exception from commit.
//如果事务被标记为全局回滚
if (globalRollbackOnly) {
throw new UnexpectedRollbackException(
"Transaction silently rolled back because it has been marked as rollback-only");
}
}
//提交过程中产生未预期的回滚异常,则回滚处理
catch (UnexpectedRollbackException ex) {
// can only be caused by doCommit
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
throw ex;
}
//对提交过程中产生的事务异常处理
catch (TransactionException ex) {
// can only be caused by doCommit
//如果回滚失败,则进行回滚异常处理
if (isRollbackOnCommitFailure()) {
doRollbackOnCommitException(status, ex);
}
else {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
}
throw ex;
}
//对提交过程中产生的异常处理
catch (RuntimeException ex) {
//如果不是在完成前调用的
if (!beforeCompletionInvoked) {
//触发完成前的回调方法
triggerBeforeCompletion(status);
}
//进行回滚异常处理
doRollbackOnCommitException(status, ex);
throw ex;
}
//对提交过程中产生的错误处理
catch (Error err) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
doRollbackOnCommitException(status, err);
throw err;
}

// Trigger afterCommit callbacks, with an exception thrown there
// propagated to callers but the transaction still considered as committed.
try {
/触发提交之后的回调操作
triggerAfterCommit(status);
}
finally {
//提交完成之后清除事务相关状态
triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
}

}
finally {
//这里会进行清除TransactionSynchronizationManager线程中保存的事务资源信息。
//在这里会根据调用的模式:例如filter-action-service-dao。则会在这里关闭connection,不会关闭session
//如果是service-dao 这样的模式,则会这次关闭session
cleanupAfterCompletion(status);
}
}


AbstractPlatformTransactionManager#cleanupAfterCompletion 源代码
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
status.setCompleted();
//清除TransactionSynchronizationManager的一些事务信息
if (status.isNewSynchronization()) {
TransactionSynchronizationManager.clear();
}
//如果是新的事务
if (status.isNewTransaction()) {
//调用HibernateTransactionManager的的实现,下面分有代码分析
doCleanupAfterCompletion(status.getTransaction());
}
//如果挂起了线程。则进行回复原来的事务到线程中
if (status.getSuspendedResources() != null) {
if (status.isDebug()) {
logger.debug("Resuming suspended transaction after completion of inner transaction");
}
resume(status.getTransaction(), (SuspendedResourcesHolder) status.getSuspendedResources());
}
}


HibernateTransactionManger#doCleanupAfterCompletion 源代码
protected void doCleanupAfterCompletion(Object transaction) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;

// Remove the session holder from the thread.
//如果是新的sessionHolder,则在线程中移除绑定
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.unbindResource(getSessionFactory());
}

// Remove the JDBC connection holder from the thread, if exposed.

if (getDataSource() != null) {
TransactionSynchronizationManager.unbindResource(getDataSource());
}

Session session = txObject.getSessionHolder().getSession();

if (this.prepareConnection && session.isConnected() && isSameConnectionForEntireSession(session)) {
// We're running with connection release mode "on_close": We're able to reset
// the isolation level and/or read-only flag of the JDBC Connection here.
// Else, we need to rely on the connection pool to perform proper cleanup.
try {
Connection con = session.connection();
DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
}
catch (HibernateException ex) {
logger.debug("Could not access JDBC Connection of Hibernate Session", ex);
}
}

//如果在事务对象中标记的是新的session,则在此被关闭。一般都是Service--dao这样的调用方式
if (txObject.isNewSession()) {
if (logger.isDebugEnabled()) {
logger.debug("Closing Hibernate Session [" + SessionFactoryUtils.toString(session) +
"] after transaction");
}
SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());
}//否从则只关闭connection。。 从filter过来的请求
else {
if (logger.isDebugEnabled()) {
logger.debug("Not closing pre-bound Hibernate Session [" +
SessionFactoryUtils.toString(session) + "] after transaction");
}
if (txObject.getSessionHolder().getPreviousFlushMode() != null) {
session.setFlushMode(txObject.getSessionHolder().getPreviousFlushMode());
}
if (!this.hibernateManagedSession) {
session.disconnect();
}
}
//清除事务对象的属性。。
txObject.getSessionHolder().clear();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: