spring 整合hibernate事物的三种配置

spring整合事物的三种配置

在配置声明事事物前,首先创建一个maven jar项目,一下是目录结构(1-0):

pom.xml 如下(1-1):

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
  </dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.6.RELEASE</version><!--4.3.14.RELEASE-->
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.10</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
  <dependency>
    <groupId>aopalliance</groupId>
    <artifactId>aopalliance</artifactId>
    <version>1.0</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.2.12.Final</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.0.6.RELEASE</version><!--4.3.14.RELEASE-->
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>5.0.6.RELEASE</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.38</version>
  </dependency>
</dependencies>
以下是主要代码块service的实现用于转账
@Service
//@Transactional(readOnly = true)
public class PayServiceImpl implements PayService {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public void transferAccounts() {
       Session session =  sessionFactory.getCurrentSession();
//        System.out.println("session:"+session);
        AccountEntity accountEntity = session.get(AccountEntity.class, 1L);
        AccountEntity accountEntity1 = session.get(AccountEntity.class, 2L);
        accountEntity.setAccountMoney(accountEntity.getAccountMoney().subtract(new BigDecimal(200)));
        accountEntity1.setAccountMoney(accountEntity1.getAccountMoney().add(new BigDecimal(200)));
        try {
            session.update(accountEntity);
            session.update(accountEntity1);
//            throw new RuntimeException();
        }catch (Exception e){
            throw new PayBusinessException("转账失败...");
        }
    }
}

声明事事物 applicationContext.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--引入配置文件属性-->
    <!--<context:property-placeholder location="classpath:datasource.properties" />-->

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:datasource.properties" />
    </bean>

    <!--配置数据源-->
    <bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
        <property name="driverClassName" value="${jdbc.driver_class}"/>
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!--整合hibernate中sessionFactory 交给spring 容器管理-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
        <property name="dataSource" ref="myDataSource" />
        <property name="packagesToScan" value="com.aop.transaction.pay" />
        <!--配置hibernate额外属性-->
        <property name="hibernateProperties">
            <props>
                <!--设置hibernate方言-->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <!--配置事物管理-->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!--配置声明性事务管理(事务应用一般放在业务层)-->

    <!--事物传播性和隔离性-->
    <!-- 事务传播行为类型 说明 PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
      PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
      PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED
      以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
      PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类
      似的操作。 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="transfer*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="insert*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="edit*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="load*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="find*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="*" propagation="SUPPORTS" read-only="true" rollback-for="com.aop.transaction.common.base.BaseException" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>

    <!--配置切入点-->
    <aop:config>
        <aop:pointcut id="pcut" expression="execution( * com.aop.transaction.pay.service.*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pcut" />
    </aop:config>

    <!--配置包扫描-->
    <context:component-scan base-package="com.aop.transaction.pay" />

</beans>

aop 拦截器 applicationContext-tx-interceptor.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--引入配置文件属性-->
    <!--<context:property-placeholder location="classpath:datasource.properties" />-->

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:datasource.properties" />
    </bean>

    <!--配置数据源-->
    <bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
        <property name="driverClassName" value="${jdbc.driver_class}"/>
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!--整合hibernate中sessionFactory 交给spring 容器管理-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
        <property name="dataSource" ref="myDataSource" />
        <property name="packagesToScan" value="com.aop.transaction.pay" />
        <!--配置hibernate额外属性-->
        <property name="hibernateProperties">
            <props>
                <!--设置hibernate方言-->
                <!--<prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>-->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <!--配置事物管理-->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- 配置声明性事务管理(事务应用一般放在业务层) -->
    <!-- 事务传播行为类型 说明 PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
        PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
        PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED
        以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
        PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类
        似的操作。 -->
    <!-- aop代理 -->
    <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <!-- 设置事务管理其 -->
        <property name="transactionManager" ref="transactionManager" />
        <!--设置事物属性-->
        <property name="transactionAttributes">
            <props>
                <!-- 设置拦截方法,可以使用通配符 -->
                <!-- 可以设置事务的传播行为,隔离级别,多个值用逗号隔开 -->
                <prop key="transfer*">PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ</prop>
                <prop key="add*">PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ</prop>
                <prop key="insert*">PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ</prop>
            </props>
        </property>
    </bean>

    <!-- 定义BeanNameAutoProxyCreatorf进行Spring的事务处理 -->
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <!-- 针对指定的bean自动生成业务代理 -->
        <property name="beanNames" value="*Service" />
        <!-- 这个属性为true时,表示被代理的是目标类本身而不是目标类的接口[cglib] -->
        <property name="proxyTargetClass">
            <value>true</value>
        </property>
        <!-- 依赖注入上面定义的事务拦截器transactionInterceptor -->
        <property name="interceptorNames">
            <list>
                <value>transactionInterceptor</value>
            </list>
        </property>
    </bean>

    <!--配置包扫描-->
    <context:component-scan base-package="com.aop.transaction.pay" />

</beans>

注解 applicationContext-tx-annotation.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--引入配置文件属性-->
    <!--<context:property-placeholder location="classpath:datasource.properties" />-->

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:datasource.properties" />
    </bean>

    <!--配置数据源-->
    <bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
        <property name="driverClassName" value="${jdbc.driver_class}"/>
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!--整合hibernate中sessionFactory 交给spring 容器管理-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
        <property name="dataSource" ref="myDataSource" />
        <property name="packagesToScan" value="com.aop.transaction.pay" />
        <!--配置hibernate额外属性-->
        <property name="hibernateProperties">
            <props>
                <!--设置hibernate方言-->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <!--配置事物管理-->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- 配置注解方式管理事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" />

    <!--配置包扫描-->
    <context:component-scan base-package="com.aop.transaction.pay" />

</beans>

测试代码:

猜你喜欢

转载自blog.csdn.net/qq_18430613/article/details/82225137