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和connectionprotected 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); } }