HibernateTransactionManager 事务管理实现

HibernateTransactionManager对事务的实现,最终都是通过处理hibernate的Transaction的commit,rollback方法完成,

  与单独的hibernate的Transaction事务没有太大的区别;但是,HibernateTransactionManager通过注入sessionfactory.

  然后在得到session,把session包装成SessionHolder(),并通过threadlocal来对象的实现和线程的绑定(threadlocal实现重点)

  最后到线程中的session取得的Transaction,

//SessionHolder对session包装,绑定到threadlocal中去
private final Map<Object, Session> sessionMap = Collections.synchronizedMap(new HashMap<Object, Session>(1));

1.主要理解这个类的 doBegin(),doGetTransaction()方法

protected void doBegin(Object transaction, TransactionDefinition definition)

 doBegin(Object transaction, TransactionDefinition definition)负责事务的创建

两个参数:

第一个参数:Object   transaction

                    会得到session和一个connection.

设置HibernateTransactionObject,获取线程中的session和connection
protected Object doGetTransaction() {
		//这是一个SPI类,代表一个SessionHolder
		HibernateTransactionObject txObject = new HibernateTransactionObject();
                //在事务中设置保存点,是否允许嵌套事务
		txObject.setSavepointAllowed(isNestedTransactionAllowed());
		
		//在绑定的线程中查找当前的session,SessionHolder是session的包装,SessionHolder绑定到threadlocal
		SessionHolder sessionHolder =
				(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
		if (sessionHolder != null) {
			.......
			txObject.setSessionHolder(sessionHolder);
		}
		else if (this.hibernateManagedSession) {
			try {
				Session session = getSessionFactory().getCurrentSession();
				.......
				txObject.setExistingSession(session);
			}
			catch (HibernateException ex) {
				.......
			}
		}
                //得到一个connection,它也是和线程绑定的
		if (getDataSource() != null) {
			ConnectionHolder conHolder = (ConnectionHolder)
					TransactionSynchronizationManager.getResource(getDataSource());
			txObject.setConnectionHolder(conHolder);
		}

		return txObject;
	}

事务开始的地方

protected void doBegin(Object transaction, TransactionDefinition definition) {
		HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;

		if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
			throw new IllegalTransactionStateException(
				......

		Session session = null;
                //如果SessionHolder没有被创建,那么这里openSession并放到SessionHolder中去
		try {
			if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
				Interceptor entityInterceptor = getEntityInterceptor();
				Session newSession = (entityInterceptor != null ?
						getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());
				if (logger.isDebugEnabled()) {
					......
				}
				txObject.setSession(newSession);
			}
			//三种得到session(OpenSessionInView,getcurrentsession,opensession),这里就从SessionHolder得到session
			session = txObject.getSessionHolder().getSession();
			
			//设置<tx>isolation,read-only属性
			if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
				// We're allowed to change the transaction settings of the JDBC Connection.
				......
				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.isReadOnly() && txObject.isNewSession()) {
				// Just set to NEVER in case of a new Session for this transaction.
				session.setFlushMode(FlushMode.MANUAL);
			}

			if (!definition.isReadOnly() && !txObject.isNewSession()) {
				// We need AUTO or COMMIT for a non-read-only transaction.
				FlushMode flushMode = session.getFlushMode();
				if (flushMode.lessThan(FlushMode.COMMIT)) {
					session.setFlushMode(FlushMode.AUTO);
					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+
				// Applies to all statements, also to inserts, updates and deletes!
				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.
                        //把hibtx事务放到txobject里面,原因是因为这个SessionHolder会和线程绑定
			txObject.getSessionHolder().setTransaction(hibTx);

			// Register the Hibernate Session's JDBC Connection for the DataSource, if set.
			if (getDataSource() != null) {
				Connection con = session.connection();
				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 + "]");
				}
				TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
				txObject.setConnectionHolder(conHolder);
			}

			// Bind the session holder to the thread.
                        //如果是新的SessionHolder,把它和线程绑定
			if (txObject.isNewSessionHolder()) {
				TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
			}
                        //SessionHolder的状态标识,你的Transaction是一个线程中的session取得的
			txObject.getSessionHolder().setSynchronizedWithTransaction(true);
		}

		catch (Exception ex) {
			if (txObject.isNewSession()) {
				try {
					if (session.getTransaction().isActive()) {
						session.getTransaction().rollback();
					}
				}
				catch (Throwable ex2) {
					logger.debug("Could not rollback Session after failed transaction begin", ex);
				}
				finally {
					SessionFactoryUtils.closeSession(session);
				}
			}
			throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);
		}
	}




你可能感兴趣的:(Hibernate,session,object,jdbc,Interceptor,null)