spring声明事务管理

一、数据库连接池

  在程序启动时建立足够的数据库连接放置在内存中(List),这些连接组成连接池由程序动态的对池中的连接进行申请,使用,释放。

  

  优势:资源重用;由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销;另一方面也增加了系统运行环境的平稳性。

     更快的系统反应速度;数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,从而减少了系统的响应时间。

     统一的连接管理,避免数据库连接泄露; 在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,避免了常规数据库连接操作中可能出现的资源泄露。

 

  常见的数据库连接池

     C3P0   Proxool   DBCP Druid

  

  配置C3P0数据源

    需要c3p0数据库连接池类库 c3p0-0.9.2.1.jar   mchange-commons-java-0.2.3.4.jar

    将C3P0数据源纳入IOC容器中

    

 1     <context:property-placeholder location="jdbc.properties"/>    
 2     <!-- ComboPooledDataSource 实现了javax.sql.DataSource接口 -->
 3     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
 4         
 5         <property name="driverClass" value="${jdbc.driverClass}"/>
 6         <property name="jdbcUrl" value="${jdbc.url}"/>
 7         <property name="user" value="${jdbc.user}"/>
 8         <property name="password" value="${jdbc.password}"/>
 9         
10         <!-- 个性化配置 -->
11         <property name="initialPoolSize" value="3"/>
12         <property name="minPoolSize" value="3"/>
13         <property name="maxPoolSize" value="3"/>
14         
15         <property name="maxIdleTime" value="21800"/>
16         <property name="maxConnectionAge" value="21800"/>
17     </bean>

    数据库连接核心配置通常是在属性配置文件中,<context:property-placeholder/>会读取jdbc.properties信息到IOC容器中。

    

    连接池数据源主要是应用于在配置hibernate的sessionFactory获取数据库连接

    

 1 <!-- 引入hibernate的sessionFactory -->
 2     <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" destroy-method="destroy">
 3         <property name="dataSource" ref="dataSource"/>
 4         
 5         <property name="hibernateProperties">
 6             <props>
 7                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
 8                 <prop key="hibernate.show_sql">true</prop>
 9                 <prop key="hibernate.format_sql">true</prop>
10                 <prop key="hibernate.hbm2ddl.auto">none</prop>
11             </props>
12         </property>
13         <property name="packagesToScan" value="proj.entity"/>
14     </bean>

    在属性dataSource注入上面配置的c3p0数据源

 

    

二、Spring事务管理  

  事务管理器:

     Spring事务管理功能核心是事务管理器,Spring为不同的数据访问框架提供了不同的事务管理器,从而支持各种数据访问框架的事务管理功能; 

     Spring为数据访问框架提供的事务管理器均实现Spring的策略接口PlatformTransactionManager,该接口定义如下方法: getTransaction()返回一个已经激活的事务或创建一个新的事务      commit()提交当前事务 rollback() 回滚当前事务

     

     Spring内置的事务管理器有:

             DataSourceTransactionManager 数据源事务管理器,用于对单个数据源进行事务管理,通常用于JDBC事务管理或者mybatis事务管理

            JdoTransactionManager Jdo事务管理器,用于Spring整合jdo时对jdo事务进行管理

            JpaTransactionManager JPA事务管理器,用于Spring整合JPA时对JPA进行数据管理

             HibernateTransactionManager Hibernate事务管理器,用于Spring整合Hibernate时对进行事务管理。

      将Hibernate事务管理器纳入IoC容器管理:     

1 <!-- 定义hibernate事务管理器 -->
2     <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
3         <!-- 注入sessionFactory -->
4         <property name="sessionFactory" ref="sessionFactory"/>
5     </bean>

    配置事务管理器后,Spring并不能自动对事务进行管理,还需要开发人员进行事务策略管理和控制

    声明式事务管理:通过在Spring配置文件中引入tx命名空间的形式,基于xml配置或者注解配置的事务管理形式,事务管理无须与侵入核心业务。

    Spring声明式事务管理是基于AOP和线程绑定技术实现,利用AOP实现开启、关闭事务并且织入到指定业务中,利用线程绑定实现事务跨越多个方法的传播。

    所以在ioc容器中已经无法获取dao层或者service层的接口实现对象,只能获取代理对象。

 

  Spring事务:

    Spring事务分为物理事务和逻辑事务:

        物理事务就是底层数据库支持的事务,如JDBC提供事务

        逻辑事务是Spring管理的事务,逻辑事务提供更丰富的控制,而且如果想得到Spring事务管理的好处,必须使用逻辑事务,因此在Spring中如果没特别强调一般就是逻辑事务     Spring声明式事务管理就是基于逻辑事务。

    事务属性: 

      事务隔离级别:用来解决并发事务时出现的问题,Spring事务隔离级别主要有以下几种:

             ISOLATION_DEFAULT:默认隔离级别,即使用底层数据库默认的隔离级别;

             ISOLATION_READ_UNCOMMITTED:读未提交;

             ISOLATION_READ_COMMITTED:提交读,一般情况下我们使用这个;

             ISOLATION_REPEATABLE_READ:可重复读;

                ISOLATION_SERIALIZABLE:序列化。

      事务只读:将事务标识为只读,只读事务不修改任何数据。

           对于JDBC只是简单的将连接设置为只读模式,对于更新将抛出异常;

           而对于一些其他ORM框架有一些优化作用,如在Hibernate中,Hibernate会话在只读事务模式下不用尝试检测和同步持久对象的状态的更新,以提高程序效率。

      

      事务传播行为: Spring管理的事务是逻辑事务,而且物理事务和逻辑事务最大差别就在于事务传播行为。

             事务传播行为用于指定在多个事务方法间调用时,事务是如何在这些方法间传播的,Spring共支持7种传播行为。 

             事务传播行为: Required:必须有逻辑事务,否则新建一个事务,表示如果当前存在一个逻辑事务,则加入该逻辑事务,否则将新建一个逻辑事务。

                    RequiresNew:创建新的逻辑事务,表示每次都创建新的逻辑事务(物理事务也是不同的)

                    Supports:支持当前事务,指如果当前存在逻辑事务,就加入到该逻辑事务,如果当前没有逻辑事务,就以非事务方式执行

                    NotSupported:不支持事务,如果当前存在事务则暂停该事务,即以非事务方式执行

                    Mandatory:必须有事务,否则抛出异常

                    Never:不支持事务,如果当前存在是事务则抛出异常

                    Nested:嵌套事务支持,如果当前存在事务,则在嵌套事务内执行,如果当前不存在事务,则创建一个新的事务

     

      基于xml的声明式事务管理:    

 1 <!-- 配置事务通知 -->
 2     <tx:advice id="txAdvice" transaction-manager="txManager">
 3         <tx:attributes>
 4              <!--  为指定的方法配置事务策略 --> 
 5               <!--  propagation="REQUIRED" propagation用于指定事务的传播行为,增删改一般都是用REQUIRED,查询操作一般指定为SUPPORT --> 
 6              <!--  read-only="false"设置事务是否为只读的,适应于查询操作,提高查询效率 --> 
 7              <!--  rollback-for用于指定出现什么样的异常当前方法所处的事务进行回滚,默认是RuntimeException --> 
 8               <tx:method name="save*" propagation="REQUIRED" /> 
 9               <tx:method name="add*" propagation="REQUIRED" /> 
10               <tx:method name="insert*" propagation="REQUIRED" /> 
11               <tx:method name="update*" propagation="REQUIRED" /> 
12               <tx:method name="modify*" propagation="REQUIRED" /> 
13               <tx:method name="edit*" propagation="REQUIRED" /> 
14               <tx:method name="delete*" propagation="REQUIRED" /> 
15               <tx:method name="remove*" propagation="REQUIRED" /> 
16               <tx:method name="get*" propagation="SUPPORTS" read-only="true" /> 
17               <tx:method name="find*" propagation="SUPPORTS" read-only="true" /> 
18               <tx:method name="count*" propagation="SUPPORTS" read-only="true" /> 
19               <tx:method name="list*" propagation="SUPPORTS" read-only="true" /> 
20               <tx:method name="*" propagation="SUPPORTS" read-only="true" /> 
21         
22         </tx:attributes>
23     
24     </tx:advice>

      

    通过<aop:advisor>指定事务切面 Spring声明式事务管理通过AOP代理方式实现事务管理,利用环绕通知TransactionInterceptor实现事务的开启及关闭,且为单通知切面

    

1 <!-- 定义切面 -->
2     <aop:config>
3         <aop:advisor advice-ref="txAdvice" pointcut="execution(* proj.service..*.*(..))"/>
4     </aop:config>

    

    dataSource --->sessionFactory ----->dao ------>service

    

posted @ 2017-06-19 19:20  山鬼幽篁  阅读(187)  评论(0编辑  收藏  举报