`
jiagou
  • 浏览: 2537140 次
文章分类
社区版块
存档分类
最新评论

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




分享到:
评论

相关推荐

    spring五种事务配置demo

    DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。...

    Spring事务配置5种方式

    DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问 时,DataSource实际为SessionFactory,TransactionManager的实现为 HibernateTransactionManager。

    Spring事务配置的五种方法

    DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。

    Spring + Hibernate + Struts 事务配置小例子(带提示框等小技巧)

    -- 事务拦截器bean需要依赖注入一个事务管理器 --&gt; &lt;!-- 下面定义事务传播属性 [ bus* 事务的方法名]--&gt; *"&gt;PROPAGATION_REQUIRED &lt;!-- 定义BeanNameAutoProxyCreator,该bean是个bean后...

    Spring事务配置的五种方式

    DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。

    spring分别与jdbc和hibernate结合的事务控制--案例

    本案例主要是分别实现Spring与jdbc和hibernate结合的事务控制,如果该案例有出入的地方,请给我留言,我们一起交流

    SSH整合&&SSH集成开发

    &lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt; &lt;!-- JTA环境的事务配置 WebLogicJtaTransactionManager"/&gt; --&gt; &lt;!-- 使用annotation...

    客户关系管理系统框架搭建(二)

    --4 创建事务管理器 aop切面--&gt; &lt;bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt; &lt;!--5 配置处理事务的注解--&gt; * 创建dao...

    SSH第7章上机.zip ACCP8.0

    -- 创建事务管理器(spring针对hibernate实现的事务管理的切面类) --&gt; &lt;bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"&gt; &lt;!-- 事务的通知类型 -...

    ssh(structs,spring,hibernate)框架中的上传下载

    Struts+Spring+Hibernate实现上传下载    本文将围绕SSH文件上传下载的主题,向您详细讲述如何开发基于SSH的Web程序。SSH各框架的均为当前最新版本:  •Struts 1.2  •Spring 1.2.5  •Hibernate 3.0  本文...

    Druid连接泄露问题重现&解决方式.pdf

    Druid连接泄露问题重现&解决方式

    Myeclipse6.0中SSH框架搭建

    -- 事务处理 --&gt; class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt; &lt;property name="sessionFactory" ref="sessionFactory"&gt;&lt;/property&gt; &lt;/bean&gt; &lt;!-- 其它Bean定义在此 --&gt; &lt;!...

    ssh框架在application.xml中配置数据源所需jar

    -- 配置事务管理器 --&gt; &lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt; &lt;/property&gt; &lt;!-- 配置事务的传播特性 --&gt; *" ...

    OA项目SSH整合框架

    -- 配置事务管理器 --&gt; &lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt; &lt;property name="sessionFactory" ref="sessionFactory"&gt;&lt;/property&gt; ...

    维生药业小项目 SSH简单学习项目

    class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt; &lt;!-- 使用annotation定义事务 --&gt; proxy-target-class="true" /&gt; &lt;!-- 使用annotation 自动注册bean,并检查@Required,@...

    spring3.2+strut2+hibernate4

    -- 事务配置管理 --&gt; &lt;bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"&gt; &lt;property name="sessionFactory" ref="sessionFactory" /&gt; &lt;/bean&gt; &lt;!-- ...

    spring 理解文件HibernateDaoSupport

    配置datasource--&gt;sessionfacrtory from dataSource---&gt;HibernateTransactionManager(impl)--&gt;PROPAGATION_REQUIRED事物隔离级别 (2).不同点: HibernateDaoSupport: 在impl中要调用的方法要...

    三大框架下分页源代码

    &lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt; &lt;!-- 新闻类型 --&gt; &lt;!-- 新闻类型 --&gt; *" ...

    springframework.5.0.12.RELEASE

    HibernateTransactionManager (unintentionally) bound to Hibernate 5.2 SharedSessionContractImplementor [SPR-17557] #22089 Spring JavaMailSenderImpl does not show proper message when recipient list is ...

    SpringMVC+Hibernate全注解整合

    class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt; &lt;!-- Spring AOP config配置切点 --&gt; (public * com.org.service.*.*(..))" id="bussinessService" /&gt; &lt;!-- 配置...

Global site tag (gtag.js) - Google Analytics