/** 对于 <tx:annotation-driven transaction-manager="txManager" /> 配置的事务(在方法上标注@Transaction) 或 使用AOP配置的事件: <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" /> <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:advisor pointcut="execution(* *..*Service*.*(..))" advice-ref="txAdvice" /> </aop:config> spring 能过AOP方式(CGLIB) 在切面(需要启用事务的方法被调用时)上调用TransactionInterceptor。 TransactionInterceptor 实现了方法拦截器: implements org.aopalliance.intercept.MethodInterceptor 示意逻辑: TransactionStatus transactionStatus = platformTransactionManager.getTransaction(); try{ //这里调用业务逻辑 }catch(Throwable ex){ platformTransactionManager.rollback(transactionStatus); throw ex; } platformTransactionManager.commit(transactionStatus); platformTransactionManager的子类 DataSourceTransactionManager 在启用事务时,从当前线程获取ConnectionHolder,如果不存在则创建一个,并绑定定到线程中。 (从线程中获取ConnectionHolder :TransactionSynchronizationManager.getResource(this.dataSource) 绑定ConnectionHolder到线程的对象为:TransactionSynchronizationManager.bindResource(this.dataSource,ConnectionHolder) ) ConnectionHolder保存在TransactionStatus中(实际子类为:DefaultTransactionStatus),以便commit或rollback可以拿到同一个Connection。 在执行sql里,如JdbcTemplate 是如何拿到同一个Connection的? Connection con = DataSourceUtils.getConnection(getDataSource()); DataSourceUtils会从当前线程中获到ConnectionHolder,如果存在直接获取使用, 如果不存在,则从DataSource中获取一个Connection, 判断是否有事务(TransactionSynchronizationManager.isSynchronizationActive()), 如果有则创建ConnectionHolder并存入当线程线(TransactionSynchronizationManager.bindResource(dataSource, ConnectionHolder);)以备下次用 如果没有,则直接返回Connnection.(无事务时每次用到Connection都会新建一个) 说明:当启用事务时,获取了 Connection(ConnctionHolder),就与当前线程绑定,JdbcTemplate 每次操作可以取得线程内的同一个Connection操作。 **/ /** 相关代码 : TransactionInterceptor方法: **/ @Override public Object invoke(final MethodInvocation invocation) throws Throwable { // Work out the target class: may be {@code null}. // The TransactionAttributeSource should be passed the target class // as well as the method, which may be from an interface. Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); // Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() { @Override public Object proceedWithInvocation() throws Throwable { return invocation.proceed();//实际的业务逻辑 } }); } /** * * */ protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) throws Throwable { // If the transaction attribute is null, the method is non-transactional. final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass); final PlatformTransactionManager tm = determineTransactionManager(txAttr); final String joinpointIdentification = methodIdentification(method, targetClass); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {//不是CallbackPreferringPlatformTransactionManager // Standard transaction demarcation with getTransaction and commit/rollback calls. //启用事务--调用PlatformTransactionManager(实际子类如DataSourceTransactionManager )的getTransaction方法启用事务 //创建TransactionInfo(内部持有PlatformTransactionManager) 并绑定到当前线程 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. retVal = invocation.proceedWithInvocation();调用实际的业务逻辑 } catch (Throwable ex) { // target invocation exception //异常rollback //txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus()); completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo);//清除信息 } //提交事务 //txInfo.getTransactionManager().commit(txInfo.getTransactionStatus()); commitTransactionAfterReturning(txInfo);//提交数据库 return retVal; } else { // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in. //如果是CallbackPreferringPlatformTransactionManager。。。。 //忽略部分代码 } } DataSourceTransactionManager是PlatformTransactionManager的子类,提供了事务处理能力。 public class DataSourceTransactionManager extends AbstractPlatformTransactionManager{ private DataSource dataSource;//内部持有数据源对象 /** * * */ protected Object doGetTransaction() { DataSourceTransactionObject txObject = new DataSourceTransactionObject();//创建DataSourceTransactionObject对象它持有ConnectionHolder txObject.setSavepointAllowed(isNestedTransactionAllowed()); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);//当前线程中获取 txObject.setConnectionHolder(conHolder, false); return txObject; } @Override protected void doBegin(Object transaction, TransactionDefinition definition) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; Connection con = null; try { if (txObject.getConnectionHolder() == null || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { Connection newCon = this.dataSource.getConnection(); if (logger.isDebugEnabled()) { logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction"); } txObject.setConnectionHolder(new ConnectionHolder(newCon), true);//获取Connection存入 ConnectionHolder 对象,内部持有Connection, } txObject.getConnectionHolder().setSynchronizedWithTransaction(true); con = txObject.getConnectionHolder().getConnection(); Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); txObject.setPreviousIsolationLevel(previousIsolationLevel); // Switch to manual commit if necessary. This is very expensive in some JDBC drivers, // so we don't want to do it unnecessarily (for example if we've explicitly // configured the connection pool to set it already). if (con.getAutoCommit()) { txObject.setMustRestoreAutoCommit(true); if (logger.isDebugEnabled()) { logger.debug("Switching JDBC Connection [" + con + "] to manual commit"); } con.setAutoCommit(false);//设置自动提交为false } txObject.getConnectionHolder().setTransactionActive(true);//标记事务启动状态 // Bind the session holder to the thread. if (txObject.isNewConnectionHolder()) { TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());//绑定ConnectionHolder到当前线程 } } catch (Throwable ex) { if (txObject.isNewConnectionHolder()) { DataSourceUtils.releaseConnection(con, this.dataSource); txObject.setConnectionHolder(null, false); } throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex); } } //启用事务,内部调用 public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { //非实际代码,忽略了部分代码 Object transaction = doGetTransaction(); try { boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); DefaultTransactionStatus status = newTransactionStatus(//创建TransactionStatus对象内部持有DataSourceTransactionObject definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); doBegin(transaction, definition); prepareSynchronization(status, definition); return status; } } /** * * DefaultTransactionStatus--持有-->DataSourceTransactionObject--持有-->ConnectionHolder--持有-》Connection-->commit() */ protected void doCommit(DefaultTransactionStatus status) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); Connection con = txObject.getConnectionHolder().getConnection(); try { con.commit();//提交 } catch (SQLException ex) { throw new TransactionSystemException("Could not commit JDBC transaction", ex); } } /** * * DefaultTransactionStatus--持有-->DataSourceTransactionObject--持有-->ConnectionHolder--持有-》Connection-->rollback() */ protected void doRollback(DefaultTransactionStatus status) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); Connection con = txObject.getConnectionHolder().getConnection(); try { con.rollback();//事务回滚 } catch (SQLException ex) { throw new TransactionSystemException("Could not roll back JDBC transaction", ex); } } JdbcTemplate 通过 DataSourceUtils 获得Connction: public static Connection doGetConnection(DataSource dataSource) throws SQLException { Assert.notNull(dataSource, "No DataSource specified"); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);//当线 if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) { conHolder.requested(); if (!conHolder.hasConnection()) { logger.debug("Fetching resumed JDBC Connection from DataSource"); conHolder.setConnection(dataSource.getConnection()); } return conHolder.getConnection(); } // Else we either got no holder or an empty thread-bound holder here. logger.debug("Fetching JDBC Connection from DataSource"); Connection con = dataSource.getConnection(); if (TransactionSynchronizationManager.isSynchronizationActive()) { logger.debug("Registering transaction synchronization for JDBC Connection"); // Use same Connection for further JDBC actions within the transaction. // Thread-bound object will get removed by synchronization at transaction completion. ConnectionHolder holderToUse = conHolder; if (holderToUse == null) { holderToUse = new ConnectionHolder(con); } else { holderToUse.setConnection(con); } holderToUse.requested(); TransactionSynchronizationManager.registerSynchronization( new ConnectionSynchronization(holderToUse, dataSource)); holderToUse.setSynchronizedWithTransaction(true); if (holderToUse != conHolder) { TransactionSynchronizationManager.bindResource(dataSource, holderToUse); } } return con; }
相关推荐
在深入探讨Spring框架中的事务传播属性之前,我们先来简要回顾一下Spring事务的基础概念。Spring框架提供了强大的事务管理功能,允许开发者通过声明式的方式管理业务逻辑中的事务边界。Spring的事务管理主要依赖于`...
在深入探讨Spring事务代理配置之前,我们先简要回顾一下Spring框架的核心概念。Spring是一个开源的Java平台,它提供了一套全面的编程和配置模型,主要用于简化企业级应用的开发。其中,依赖注入(Dependency ...
在深入探讨Spring事务管理配置之前,我们先简要回顾一下Spring框架的核心概念。Spring是一个开源的Java平台,它提供了一套全面的编程和配置模型,旨在简化企业级应用的开发。其中,事务管理是Spring框架中的一个重要...
Spring通过`applicationContext.xml`配置文件来配置应用上下文,这里可以定义Bean、事务管理、连接池等。Spring还提供了与iBatis的集成,使得事务管理和DAO层的数据库操作得以统一管理。 Struts2是MVC模式的具体...
2. AOP(面向切面编程):Spring.NET提供了AOP支持,允许开发者定义横切关注点(如日志、事务管理等),并将其与业务逻辑分离,提高了代码的可重用性和可维护性。 3. 数据访问支持:Spring.NET集成了多种数据访问...
在没有使用Spring事务管理时,通常需要手动获取和释放数据库连接,以及处理事务开始、提交和回滚。Spring通过DataSourceTransactionManager简化了这一过程,自动处理连接和事务,确保事务的一致性。 总的来说,...
在本文中,我们将深入探讨如何将Spring MVC 3.1与MyBatis 3.1框架集成,并讨论其中涉及的关键技术,如事务管理、分页和JSON数据交换。此外,我们还将简要提及开发环境中使用的工具,如Eclipse 4.3、Maven 3.0.5和...
- **数据访问/集成(Data Access/Integration)**: Spring提供了丰富的数据访问抽象层,包括JDBC、ORM(如Hibernate、JPA等)、事务管理和异常处理等,大大简化了数据库操作。 - **Web支持**: Spring提供了强大的Web...
以上只是Spring框架部分核心模块的简要介绍,每个模块都包含了大量的类和接口,它们共同构成了一个强大且灵活的开发平台,帮助开发者高效地构建复杂的企业级应用。通过理解并熟练掌握这些jar包中的知识点,开发者...
1. **简介**:这部分简要介绍了Spring框架的基本概念、设计理念和核心模块,帮助初学者快速理解Spring的核心价值。 2. **快速入门**:提供了快速上手的教程,指导如何创建第一个Spring项目,包括配置环境、编写代码...
最后一章简要展望了Spring 4.0版本的发展趋势和新特性。Spring框架一直在不断地发展和完善,以适应不断变化的技术需求。这一章为读者提供了关于未来版本的一些洞察,帮助他们了解Spring框架的演进方向。 通过上述...
以下是压缩包中各文件的简要说明: 1. "Struts+Spring+Hibernatewzzsgcdlz.rar" - 这个文件可能包含了一套教程,讲解如何将Spring与另外两个流行框架Struts和Hibernate集成。Struts是一个用于构建MVC架构的Java Web...
在介绍部分,文档首先提供了快速入门指南,这包括对Spring for Apache Kafka的简要介绍以及与Kafka的兼容性信息。对于想要快速上手的读者,文档提供了使用Java配置和Spring Boot两种快速入门方法。通过这些指南,...
4. **AOP(面向切面编程)**:Spring支持AOP,允许开发者定义“切面”,将关注点如日志、事务管理等与业务逻辑分离,提高代码的可复用性和可维护性。 5. **JDBC模板**:Spring JDBC模块提供了一种简化JDBC编码的...
以上是对Spring框架及其相关技术栈的简要介绍。对于准备进入BAT等大厂的开发者来说,掌握Spring框架的核心知识是非常必要的。不仅需要了解基本的概念,还需要深入学习其实现原理,这样才能在实际项目中更加灵活地...
在探讨Spring 2.5到3.0以及Hibernate 3.3的Jar包之前,我们先简要回顾一下这两个框架的基本概念。 #### Spring 框架简介 Spring是一个开源的应用框架,它提供了一个全面的编程模型,旨在简化Java应用程序的开发过程...
以上只是Spring框架部分组件的简要介绍,实际的"spring libs.zip"文件可能还包括其他扩展或特定场景的库,如Spring Data(用于数据访问)、Spring Security(安全框架)等。理解并熟练掌握这些库的使用,对于开发高...
以上是对《Beginning Spring》各章节内容的简要介绍。本书不仅适合初学者入门,也适合有一定经验的开发者作为参考书阅读。希望通过对这些知识点的学习,能够帮助大家更好地掌握Spring框架,并应用于实际项目开发中。
- **发送者和接收者:** 详细说明了消息发送者和接收者的角色,以及它们如何与通道交互。 - **端点配置:** 讲解了如何配置端点来发送或接收消息。 - **自定义端点:** 探讨了如何创建自定义的端点以满足特定的需求...