Spring框架总结(十二)
问题引入:
程序的“事务控制”, 可以用aop实现! 即只需要写一次,运行时候动态植入到业务方法上。
一个业务的成功: 调用的service是执行成功的,意味着service中调用的所有的dao是执行成功的。 事务应该在Service层统一控制。
1、名词解释
细粒度的事务控制: 可以对指定的方法、指定的方法的某几行添加事务控制.(比较灵活,但开发起来比较繁琐: 每次都要开启、提交、回滚.)
粗粒度的事务控制: 只能给整个方法应用事务,不可以对方法的某几行应用事务。(因为aop拦截的是方法。)
编程式事务控制
程序员手动控制事务,就叫做编程式事务控制。
声明式事务控制
Spring提供了对事务的管理, 这个就叫声明式事务管理。
Spring提供了对事务控制的实现。用户如果想用Spring的声明式事务管理,只需要在配置文件中配置即可; 不想使用时直接移除配置。这个实现了对事务控制的最大程度的解耦。 Spring声明式事务管理,核心实现就是基于Aop。
编程式事务控制与声明式事务控制实现
2、编程式事务控制
Jdbc代码:
Conn.setAutoCommite(false); // 设置手动控制事务
Hibernate代码:
Session.beginTransaction(); // 开启一个事务
声明式事务控制实现
Spring声明式事务管理器类:
Jdbc技术:DataSourceTransactionManager
Hibernate技术:HibernateTransactionManager
3、声明式事务管理
步骤:
1) 引入spring-aop相关的4个jar文件
spring-aop\aopalliance.jar
aspectjrt.jar
aspectjweaver.jar
spring-aop-3.2.5.RELEASE.jar
2) 引入aop名称空间 【XML配置方式需要引入】
3) 引入tx名称空间 【事务方式必须引入】
事例编辑
1、bean.xml(注意:
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
加载了这几个schme和相关的命名
)
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:p="http://www.springframework.org/schema/p" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 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/context 10 http://www.springframework.org/schema/context/spring-context.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop.xsd 13 http://www.springframework.org/schema/tx 14 http://www.springframework.org/schema/tx/spring-tx.xsd"> 15 <!-- 数据对像.c3p0连接池 --> 16 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 17 <property name="driverClass" value="com.mysql.jdbc.Driver"></property> 18 <property name="jdbcUrl" value="jdbc:mysql:///springmvcdb"></property> 19 <property name="user" value="root"></property> 20 <property name="password" value="123456"></property> 21 <property name="initialPoolSize" value="3"></property> 22 <property name="maxPoolSize" value="10"></property> 23 <property name="maxStatements" value="100"></property> 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="deptDao" class="com.liuyang.xml.action.Dept_Dao"> 34 <property name="jdbcTemplate" ref="jdbcTemplate"></property> 35 </bean> 36 37 <!-- service实现 --> 38 <bean id="deptService" class="com.liuyang.xml.action.Dept_Service"> 39 <property name="dept_Dao" ref="deptDao"></property> 40 </bean> 41 42 <!-- #############5. Spring声明式事务管理配置############### --> 43 <!-- 5.1 配置事务管理器类 --> 44 <bean id="txManager" 45 class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 46 <property name="dataSource" ref="dataSource"></property> 47 </bean> 48 49 <!-- 5.2 配置事务增强(如果管理事务?) --> 50 <tx:advice id="txAdvice" transaction-manager="txManager"> 51 <tx:attributes> 52 <tx:method name="*" read-only="false" /> 53 </tx:attributes> 54 </tx:advice> 55 56 <!-- 5.3 Aop配置: 拦截哪些方法(切入点表表达式) + 应用上面的事务增强配置 --> 57 <aop:config> 58 <aop:pointcut 59 expression="execution(* com.liuyang.xml.action.Dept_Service.ServiceSave(..))" 60 id="pt" /> 61 <aop:advisor advice-ref="txAdvice" pointcut-ref="pt" /> 62 </aop:config> 63 64 </beans>
2、创建user
1 public class Dept_user { 2 private int deptId; 3 private String deptName; 4 5 public int getDeptId() { 6 return deptId; 7 } 8 9 public void setDeptId(int deptId) { 10 this.deptId = deptId; 11 } 12 13 public String getDeptName() { 14 return deptName; 15 } 16 17 public void setDeptName(String deptName) { 18 this.deptName = deptName; 19 } 20 }
3、创建dao
1 public class Dept_Dao { 2 3 private JdbcTemplate jdbcTemplate; 4 5 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { 6 this.jdbcTemplate = jdbcTemplate; 7 } 8 9 public void save(Dept_user dept_action) { 10 String sql = "insert into t_dept(deptName) values(?);"; 11 jdbcTemplate.update(sql, dept_action.getDeptName()); 12 } 13 14 }
4、创建service
1 public class Dept_Service { 2 private Dept_Dao dept_Dao; 3 4 public void setDept_Dao(Dept_Dao dept_Dao) { 5 this.dept_Dao = dept_Dao; 6 } 7 8 public void ServiceSave(Dept_user dept_action) { 9 dept_Dao.save(dept_action); 10 } 11 12 }
5、创建测试的数据在数据库
1 SET FOREIGN_KEY_CHECKS=0; 2 3 -- ---------------------------- 4 -- Table structure for `t_dept` 5 -- ---------------------------- 6 DROP TABLE IF EXISTS `t_dept`; 7 CREATE TABLE `t_dept` ( 8 `deptId` varchar(10) NOT NULL DEFAULT '', 9 `deptName` varchar(50) DEFAULT NULL 10 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 11 12 -- ---------------------------- 13 -- Records of t_dept 14 -- ---------------------------- 15 INSERT INTO `t_dept` VALUES ('22', 'test'); 16 INSERT INTO `t_dept` VALUES ('10', '市场部'); 17 INSERT INTO `t_dept` VALUES ('12', '财务部'); 18 INSERT INTO `t_dept` VALUES ('9', '应用开发部'); 19 INSERT INTO `t_dept` VALUES ('', 'test'); 20 INSERT INTO `t_dept` VALUES ('', 'test');
6、测试
1 @SuppressWarnings("resource") 2 public class App { 3 4 @Test 5 public void testApp() throws Exception { 6 ApplicationContext ac = new ClassPathXmlApplicationContext( 7 "com/liuyang/xml/action/beanTemplate.xml"); 8 9 Dept_user dept = new Dept_user(); 10 dept.setDeptId(15); 11 dept.setDeptName("王小二"); 12 13 Dept_Service deptService = (Dept_Service) ac.getBean("deptService"); 14 deptService.ServiceSave(dept); 15 16 } 17 }
加上事物以后,遇到错误异常,事物会不将数据插入到表格中,比如
1 public void ServiceSave(Dept_user dept_action) { 2 dept_Dao.save(dept_action); 3 int i = 1/0; 4 dept_Dao.save(dept_action); 5 }
方法中加入如上设置,事物就不会回滚.