HibernateTransactionManager配单例事务

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

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

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

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

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

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

  1. protected void doBegin(Object transaction, TransactionDefinition definition) 
protected void doBegin(Object transaction, TransactionDefinition definition)

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

两个参数:

第一个参数:Object   transaction

                    会得到session和一个connection.

设置HibernateTransactionObject,获取线程中的session和connection
  1. protected Object doGetTransaction() { 
  2.         //这是一个SPI类,代表一个SessionHolder 
  3.         HibernateTransactionObject txObject = new HibernateTransactionObject(); 
  4.                 //在事务中设置保存点,是否允许嵌套事务 
  5.         txObject.setSavepointAllowed(isNestedTransactionAllowed()); 
  6.          
  7.         //在绑定的线程中查找当前的session,SessionHolder是session的包装,SessionHolder绑定到threadlocal 
  8.         SessionHolder sessionHolder = 
  9.                 (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); 
  10.         if (sessionHolder != null) { 
  11.             ....... 
  12.             txObject.setSessionHolder(sessionHolder); 
  13.         } 
  14.         else if (this.hibernateManagedSession) { 
  15.             try
  16.                 Session session = getSessionFactory().getCurrentSession(); 
  17.                 ....... 
  18.                 txObject.setExistingSession(session); 
  19.             } 
  20.             catch (HibernateException ex) { 
  21.                 ....... 
  22.             } 
  23.         } 
  24.                 //得到一个connection,它也是和线程绑定的 
  25.         if (getDataSource() != null) { 
  26.             ConnectionHolder conHolder = (ConnectionHolder) 
  27.                     TransactionSynchronizationManager.getResource(getDataSource()); 
  28.             txObject.setConnectionHolder(conHolder); 
  29.         } 
  30.  
  31.         return txObject; 
  32.     } 
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;
	}

事务开始的地方

  1. protected void doBegin(Object transaction, TransactionDefinition definition) { 
  2.         HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; 
  3.  
  4.         if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) { 
  5.             throw new IllegalTransactionStateException( 
  6.                 ...... 
  7.  
  8.         Session session = null
  9.                 //如果SessionHolder没有被创建,那么这里openSession并放到SessionHolder中去 
  10.         try
  11.             if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) { 
  12.                 Interceptor entityInterceptor = getEntityInterceptor(); 
  13.                 Session newSession = (entityInterceptor != null
  14.                         getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession()); 
  15.                 if (logger.isDebugEnabled()) { 
  16.                     ...... 
  17.                 } 
  18.                 txObject.setSession(newSession); 
  19.             } 
  20.             //三种得到session(OpenSessionInView,getcurrentsession,opensession),这里就从SessionHolder得到session 
  21.             session = txObject.getSessionHolder().getSession(); 
  22.              
  23.             //设置<tx>isolation,read-only属性 
  24.             if (this.prepareConnection && isSameConnectionForEntireSession(session)) { 
  25.                 // We're allowed to change the transaction settings of the JDBC Connection. 
  26.                 ...... 
  27.                 Connection con = session.connection(); 
  28.                 Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); 
  29.                 txObject.setPreviousIsolationLevel(previousIsolationLevel); 
  30.             } 
  31.             else
  32.                 // Not allowed to change the transaction settings of the JDBC Connection. 
  33.                 ...... 
  34.             } 
  35.  
  36.             if (definition.isReadOnly() && txObject.isNewSession()) { 
  37.                 // Just set to NEVER in case of a new Session for this transaction. 
  38.                 session.setFlushMode(FlushMode.MANUAL); 
  39.             } 
  40.  
  41.             if (!definition.isReadOnly() && !txObject.isNewSession()) { 
  42.                 // We need AUTO or COMMIT for a non-read-only transaction. 
  43.                 FlushMode flushMode = session.getFlushMode(); 
  44.                 if (flushMode.lessThan(FlushMode.COMMIT)) { 
  45.                     session.setFlushMode(FlushMode.AUTO); 
  46.                     txObject.getSessionHolder().setPreviousFlushMode(flushMode); 
  47.                 } 
  48.             } 
  49.  
  50.             Transaction hibTx; 
  51.  
  52.             // Register transaction timeout. 
  53.             int timeout = determineTimeout(definition); 
  54.             if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { 
  55.                 // Use Hibernate's own transaction timeout mechanism on Hibernate 3.1+ 
  56.                 // Applies to all statements, also to inserts, updates and deletes! 
  57.                 hibTx = session.getTransaction(); 
  58.                 hibTx.setTimeout(timeout); 
  59.                 hibTx.begin(); 
  60.             } 
  61.             else
  62.                 // Open a plain Hibernate transaction without specified timeout. 
  63.                                 //创建并开始事务 
  64.                 hibTx = session.beginTransaction(); 
  65.             } 
  66.  
  67.             // Add the Hibernate transaction to the session holder. 
  68.                         //把hibtx事务放到txobject里面,原因是因为这个SessionHolder会和线程绑定 
  69.             txObject.getSessionHolder().setTransaction(hibTx); 
  70.  
  71.             // Register the Hibernate Session's JDBC Connection for the DataSource, if set. 
  72.             if (getDataSource() != null) { 
  73.                 Connection con = session.connection(); 
  74.                 ConnectionHolder conHolder = new ConnectionHolder(con); 
  75.                 if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { 
  76.                     conHolder.setTimeoutInSeconds(timeout); 
  77.                 } 
  78.                 if (logger.isDebugEnabled()) { 
  79.                     logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]"); 
  80.                 } 
  81.                 TransactionSynchronizationManager.bindResource(getDataSource(), conHolder); 
  82.                 txObject.setConnectionHolder(conHolder); 
  83.             } 
  84.  
  85.             // Bind the session holder to the thread. 
  86.                         //如果是新的SessionHolder,把它和线程绑定 
  87.             if (txObject.isNewSessionHolder()) { 
  88.                 TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder()); 
  89.             } 
  90.                         //SessionHolder的状态标识,你的Transaction是一个线程中的session取得的 
  91.             txObject.getSessionHolder().setSynchronizedWithTransaction(true); 
  92.         } 
  93.  
  94.         catch (Exception ex) { 
  95.             if (txObject.isNewSession()) { 
  96.                 try
  97.                     if (session.getTransaction().isActive()) { 
  98.                         session.getTransaction().rollback(); 
  99.                     } 
  100.                 } 
  101.                 catch (Throwable ex2) { 
  102.                     logger.debug("Could not rollback Session after failed transaction begin", ex); 
  103.                 } 
  104.                 finally
  105.                     SessionFactoryUtils.closeSession(session); 
  106.                 } 
  107.             } 
  108.             throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex); 
  109.         } 
  110.     } 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值