声明式的事务管理

hithyc 2017-10-24

步骤 1.配置C3P0数据库连接池 2.配置sessionFactory工厂 3.配置事务管理器 4.配置通知 5.配置Aop

配置C3P0数据库连接池

  • 连接池就是数据库在程序连接的时候会生成指定的数据库链接,在访问的数据库的时候会优先选择使用连接池里的数据库链接,当连接池内的链接数量达到上限的时候,才会到数据库获得新的链接,连接池内的链接会在关闭链接和达到时间上限的时候依然回到数据库连接池。连接池的种类很多如,C3P0,Proxool,DBCP,Druid,阿里等等
  • 为了减轻数据的多个链接,影响数据库的性能,以及会出现数据库的8小时陷阱,所以需要用数据库连接池来处理
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <!-- 初始化连接数 -->
        <property name="initialPoolSize" value="3"/>
        <!-- 最小连接数  -->
        <property name="minPoolSize" value="3"/>
        <!-- 最大连接时间 -->
        <property name="maxConnectionAge" value="28800"/>
    
    </bean>

配置sessionFactory工厂

  • 操作数据库的就必须要获得sessionFactory工厂来得到session来操作数据库,
  • 将连接池得配置注入到sessionFactory配置内。
  • <!-- 配置sessionFactory -->
       <bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"  id="sessionFactory">
         <!-- 关联数据源和SessionFactory -->
          <property name="dataSource" ref="dataSource"/>
           <!-- hiberna的配置文件 -->
          <property name="hibernateProperties" >
          <props>
          <!-- 数据库方言的设置 -->
      				<prop key="hibernate.dialect">${dialect}</prop>
      				<!--设置session上下文这里不能设置thread,设置thread就需要手动管理并不能让Spring管理,要么不指定要么指定下面的类 -->
      				<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
      				<!-- 显示SQl和格式化SQl  -->
      				<prop key="hibernate.show_sql">${showSql}</prop>
          </props>    
          </property>
          <property name="packagesToScan" value="com.zhidi.entity">
          </property>
       </bean>

配置事务管理器

  • 事务管理器就是将业务逻辑的前后的事务集中到事务管理器集中处理,可以优化了我们的代码和避免不必要的事务的开启和关闭,
  • 事务管理器的配置不会自动开启事务,依然需要人为的管理和控制
<!-- 配置事务管理器 -->
     <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
     <property name="sessionFactory" ref="sessionFactory"/>
     </bean>

配置通知 (以下是XML的注入)

  • 将所需要执行的业务方法配置事务。name属性值是我们需要通知的对象也是主业务逻辑,在后面配置事务的传播方式,确定此业务是否需要开启事务,开启事务的话是可以对数据库进行增删改的,
<!--配置通知  -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
    <!-- 配置增删改的方法 这里设置的方法可以自动注入 这里的name的方法可以自动搜索 可以定义多个常用的方法名 -->
    <tx:method name="save*" propagation="REQUIRED"/>
    <tx:method name="delect*" propagation="REQUIRED"/>
    <tx:method name="update*" propagation="REQUIRED"/>
    <!--配置查询的方法  REQUIRED表示没有逻辑事务的情况下会自己生产一个,如果有就自动加入
       SUPPORTS是如果当前有逻辑事务存在就加入到事务中,如果没有就以非事务进行处理 -->
    <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
    </tx:advice>

配置Aop

  • 将配置好的数据库的AOP的具体实现通过切入点注入到对应的地方去引用。

    <!-- aop配置 -->
       <aop:config>
       <!--将配置好的通知嵌入到切点相关联  -->
       <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.zhidi.service.impl..*.*(..))" />
       </aop:config>

注解的模式取代后面两个

<!-- 注解模式的注入-->
<tx:annotation-driven transaction-manager="txManager"/>

###注解配置的代码类的实现。。。。

  • @Transactional在不添加属性值,是按默认的属性赋值,具体看源码
  • @Transactional
      @Repository
      public class EmpDao implements EmpDaoImpl {
        
      
      	@Autowired
      	private DataSource dataSource;
          
          @Autowired
          private SessionFactory sessionFactory;
          
          
          public Session getSession() {
          	
      		return sessionFactory.getCurrentSession();
      	}
      	
      	public DataSource getDataSource() {
      		
      		return dataSource;
      	}
      	@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
      	public void get(){
      		Session session = getSession();
      		Transaction tx = session.beginTransaction();
      		   Emp emp = (Emp) session.get(Emp.class, 2);
      		   System.out.println(emp);
      		tx.commit();
      	}

相关推荐