Java进阶知识25 Spring的事务管理(事务回滚)

1、事务控制概述  

  1.1、编程式事务控制
         自己手动控制事务,就叫做编程式事务控制。
         Jdbc代码: connection.setAutoCommit(false);  // 设置手动控制事务
         Hibernate代码: session.beginTransaction();   // 开启一个事务
                                transaction.rollback();  //事务回滚
       细粒度的事务控制: 可以对指定的方法、指定的方法的某几行添加事务控制】 (比较灵活,但开发起来比较繁琐: 每次都要开启、提交、回滚.)

  1.2、Spring声明式事务控制
         Spring提供了对事务的管理,这个就叫做声明式事务管理。
         Spring提供了对事务控制的实现。用户如果想用Spring的声明式事务管理,只需要在配置文件中配置即可; 不想使用时直接移除配置。这个实现了对事务控制的最大程度的解耦。
         Spring声明式事务管理,核心实现就是基于Aop。
       粗粒度的事务控制: 只能给整个方法应用事务,不可以对方法的某几行应用事务。】(因为aop拦截的是方法。)

2、Spring声明式事务管理器类  

   Jdbc技术:DataSourceTransactionManager
   Hibernate技术:HibernateTransactionManager

2.1、JDBC技术

 1 <!-- ############Spring声明式事务管理配置########### -->
 2     <!-- 配置事务管理器 -->
 3     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 4         <property name="dataSource" ref="dataSource"></property>
 5     </bean>
 6     
 7     <!-- 配置事务增强(针对DAO层) -->
 8     <tx:advice transaction-manager="transactionManager" id="transactionAdvice">
 9         <tx:attributes>  <!--  *代表dao层的所有方法 -->
10             <tx:method name="*" read-only="false"/>
11         </tx:attributes>
12     </tx:advice>
13     
14     <!-- AOP配置:配置切入点表达式 -->
15     <aop:config>
16         <aop:pointcut expression="execution(* com.shore.service.impl.UserService.save(..))" id="pt"/>
17         <aop:advisor advice-ref="transactionAdvice" pointcut-ref="pt"/>
18     </aop:config>

说明:上面代码是在Spring 配置文件(beans.xml)里面的,只要DAO层或Service层某个方法出现异常,都会引起“事务回滚”,即:该异常方法对数据库表的CRUD操作都会撤销回来。如果不要这个Spring事务管理,删除即可,不会对其他代码产生影响的;这段代码的主要用作就是:当DAO层或Service层某个方法出现异常时,进行事务回滚。

2.2、Hibernate技术

 1 <!-- ############Spring声明式事务管理配置########### -->
 2     <!-- 配置事务管理器 -->
 3     <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
 4         <property name="sessionFactory" ref="sessionFactory"></property>
 5     </bean>
 6     
 7     <!-- 配置事务增强(针对DAO层) -->
 8     <tx:advice transaction-manager="transactionManager" id="transactionAdvice">
 9         <tx:attributes>  <!-- *代表DAO层的所有方法 -->
10             <tx:method name="*" read-only="false"/>
11         </tx:attributes>
12     </tx:advice>
13     
14     <!-- AOP配置:配置切入点表达式 -->
15     <aop:config>    <!-- 第一个*表示返回值类型;第二个*表示service层下的所有接口实现类;第三个*表示每个接口实现类下的所有方法 -->
16         <aop:pointcut expression="execution(* com.shore.service.impl.*.*(..))" id="pt"/>
17         <aop:advisor advice-ref="transactionAdvice" pointcut-ref="pt"/>
18     </aop:config>

说明:和JDBC技术的一样,只有“配置事务管理器”处的代码不一样。

 

 

  附录  

1、Spring+JDBC 版本:

接口实现类(UserDao)

 1 public class UserDao implements IUserDao{
 2     private JdbcTemplate jdbcTemplate;  //这里与Spring的配置文件 DAO层 对接
 3     
 4     public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
 5         this.jdbcTemplate = jdbcTemplate;
 6     }
 7     
 8     @Override
 9     public void save(User user) {
10         jdbcTemplate.update("insert into user(name) values(?)",user.getName(),user.getAge());
11     }
12 }

我测试用到的完整Spring配置文件(beans.xml)

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xmlns:tx="http://www.springframework.org/schema/tx"
 6     xsi:schemaLocation="
 7        http://www.springframework.org/schema/beans
 8        http://www.springframework.org/schema/beans/spring-beans.xsd
 9        http://www.springframework.org/schema/tx
10        http://www.springframework.org/schema/tx/spring-tx.xsd
11        http://www.springframework.org/schema/aop
12        http://www.springframework.org/schema/aop/spring-aop.xsd">
13 
14     <!-- c3p0数据库连接池配置 -->
15     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
16         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
17         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_0301_transaction"></property>
18         <property name="user" value="root"></property>
19         <property name="password" value="zhaoyong"></property>
20         <property name="initialPoolSize" value="3"></property>
21         <property name="maxPoolSize" value="100"></property>
22         <property name="maxStatements" value="200"></property>
23         <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
24         <property name="acquireIncrement" value="2"></property>
25     </bean>
26 
27     <!-- JDBCTemplate -->
28     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
29         <property name="dataSource" ref="dataSource"></property>  <!-- 这里和下面的“配置事务管理器”处对接 -->
30     </bean>
31     
32     <!-- Dao层 -->
33     <bean id="userDao" class="com.shore.dao.impl.UserDao">
34         <property name="jdbcTemplate" ref="jdbcTemplate"></property>
35     </bean>
36     
37     <!-- Service层 -->
38     <bean id="userService" class="com.shore.service.impl.UserService">
39         <property name="userDao" ref="userDao"></property>
40     </bean>
41     
42     <!-- Action层 -->
43     <bean id="userAction" class="com.shore.action.UserAction">
44         <property name="userService" ref="userService"></property>
45     </bean>
46     
47     
48     <!-- ############Spring声明式事务管理配置########### -->
49     <!-- 配置事务管理器 -->
50     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
51         <property name="dataSource" ref="dataSource"></property>
52     </bean>
53     
54     <!-- 配置事务增强(针对DAO层) -->
55     <tx:advice transaction-manager="transactionManager" id="transactionAdvice">
56         <tx:attributes>  <!-- *代表DAO层的所有方法 -->
57             <tx:method name="*" read-only="false"/>
58         </tx:attributes>
59     </tx:advice>
60     
61     <!-- AOP配置:配置切入点表达式 -->
62     <aop:config>
63         <aop:pointcut expression="execution(* com.shore.service.impl.UserService.save(..))" id="pt"/>
64         <aop:advisor advice-ref="transactionAdvice" pointcut-ref="pt"/>
65     </aop:config>
66 </beans>

2、Spring+Hibernate 版本:

接口实现类(UserDao)

 1 public class UserDao implements IUserDao{
 2     //从IoC容器注入SessionFactory
 3     private SessionFactory sessionFactory;  //这里与Spring的配置文件 DAO层 对接
 4     public void setSessionFactory(SessionFactory sessionFactory) {
 5         this.sessionFactory = sessionFactory;
 6     }
 7 
 8     @Override
 9     public void save(User user) {
10         sessionFactory.getCurrentSession().save(user);
11     }
12 }

我测试用到的完整Spring配置文件(beans.xml)

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 4     xmlns:tx="http://www.springframework.org/schema/tx"
 5     xsi:schemaLocation="
 6        http://www.springframework.org/schema/beans
 7        http://www.springframework.org/schema/beans/spring-beans.xsd
 8        http://www.springframework.org/schema/tx
 9        http://www.springframework.org/schema/tx/spring-tx.xsd
10        http://www.springframework.org/schema/aop
11        http://www.springframework.org/schema/aop/spring-aop.xsd">
12 13 <!-- Spring去读取Hibernate配置文件(hibernate.cfg.xml) --> 14 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 15 <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> 16 </bean> 17 18 <bean id="userDao" class="com.shore.dao.impl.UserDao"> 19 <property name="sessionFactory" ref="sessionFactory"></property> <!-- 这里和下面的“配置事务管理器”处对接 --> 20 </bean> 21 22 <bean id="userService" class="com.shore.service.impl.UserService"> 23 <property name="userDao" ref="userDao"></property> 24 </bean> 25
26 <bean id="userAction" class="com.shore.action.UserAction">
27 <property name="userService" ref="userService"></property>
28 </bean>
29 30 <!-- ############Spring声明式事务管理配置########### --> 31 <!-- 配置事务管理器 --> 32 <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 33 <property name="sessionFactory" ref="sessionFactory"></property> 34 </bean> 35 36 <!-- 配置事务增强(针对DAO层) --> 37 <tx:advice transaction-manager="transactionManager" id="transactionAdvice"> 38 <tx:attributes> <!-- *代表DAO层的所有方法 --> 39 <tx:method name="*" read-only="false"/> 40 </tx:attributes> 41 </tx:advice> 42 43 <!-- AOP配置:配置切入点表达式 --> 44 <aop:config> <!-- 第一个*表示返回值类型;第二个*表示service层下的所有接口实现类;第三个*表示每个接口实现类下的所有方法 --> 45 <aop:pointcut expression="execution(* com.shore.service.impl.*.*(..))" id="pt"/> 46 <aop:advisor advice-ref="transactionAdvice" pointcut-ref="pt"/> 47 </aop:config> 48 </beans>

我测试用到的完整Hibernate配置文件(hibernate.cfg.xml)

 1 <?xml version='1.0' encoding='utf-8'?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5 
 6 <hibernate-configuration>
 7     <session-factory>
 8         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
 9         <property name="connection.url">jdbc:mysql://localhost:3306/spring_hibernate</property>
10         <property name="connection.username">root</property>
11         <property name="connection.password">123456</property>
12 
13         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
14         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
15         <property name="show_sql">true</property>
16         <property name="format_sql">true</property>
17         <property name="hbm2ddl.auto">update</property>
18 
19         <mapping resource="com/shore/entity/User.hbm.xml"/>
20     </session-factory>
21 </hibernate-configuration>

实体类(User)的Hibernate配置文件(User.hbm.xml)

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5         
 6 <hibernate-mapping package="com.shore.entity">
 7     <class name="User">  
 8         <id name="id"> 
 9             <generator class="native"/>
10         </id>
11         <property name="name" type="java.lang.String"/> 
12         <property name="age" type="java.lang.Integer"/> 
13     </class>
14 </hibernate-mapping>

 

 

 

 

 

原创作者:DSHORE

作者主页:http://www.cnblogs.com/dshore123/

原文出自:https://www.cnblogs.com/dshore123/p/11830488.html

欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!

posted @ 2019-11-10 15:42  DSHORE  阅读(3305)  评论(0编辑  收藏  举报