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 歡迎轉載,轉載務必說明出處。(如果本文對您有幫助,可以點擊一下右下角的 推薦,或評論,謝謝!) |