Spring事务管理

Posted 乔克叔叔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring事务管理相关的知识,希望对你有一定的参考价值。

配置环境,导入相应jar包:ioc/aop/jdbcTemplate/c3p0连接池的相应jar包

程序大致说明:创建数据库

表结构:

dao中两个方法,lessSalary(),moreSalary()用来模拟转账,

然后再service中调用dao中的两个方法完成转账操作

 

一.不使用事务:

 1  1 package org.dao;
 2  2 
 3  3 import org.springframework.jdbc.core.JdbcTemplate;
 4  4 
 5  5 
 6  6 public class Dao {
 7  7     private JdbcTemplate jdbcTemplate;
 8  8     
 9  9     public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
10 10         this.jdbcTemplate = jdbcTemplate;
11 11     }
12 12 
13 13     //小王转账给小马  金额2000
14 14     public void lessSalary() {
15 15         // TODO Auto-generated method stub
16 16         String sql="update acountmoney set salary=salary+? where name=?";
17 17         jdbcTemplate.update(sql,-2000,"小王");    
18 18     }
19 19 
20 20     public void moreSalary() {
21 21         // TODO Auto-generated method stub
22 22         String sql="update acountmoney set salary=salary+? where name=?";
23 23         jdbcTemplate.update(sql,2000,"小马");;
24 24     }
25 25 
26 26 }

 

 1 package org.service;
 2 
 3 import org.dao.Dao;
 4 
 5 public class Service {
 6     private Dao dao;
 7 
 8     public void setDao(Dao dao) {
 9         this.dao = dao;
10     }
11     public void changeSalary(){
12         System.out.println("开始转账。。。。。。。。");
13         this.dao.lessSalary();
14         this.dao.moreSalary();
15         System.out.println("转账成功。。。。。。。。。。。");
16     }
17 }
 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:context="http://www.springframework.org/schema/context"
 5     xmlns:aop="http://www.springframework.org/schema/aop"
 6     xmlns:tx="http://www.springframework.org/schema/tx"
 7     xsi:schemaLocation="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="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
17         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
18         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/account"></property>
19         <property name="user" value="root"></property>
20         <property name="password" value="jay571018"></property>
21     </bean>
22     
23     <!-- 创建dao对象  注入jdbcTemplate-->
24     <bean id="dao" class="org.dao.Dao">
25         <property name="jdbcTemplate" ref="jdbcTemplate"></property>
26     </bean>
27     
28     <!-- 创建service对象  注入dao-->
29     <bean id="service" class="org.service.Service">
30         <property name="dao" ref="dao"></property>
31     </bean>
32     
33     <!-- 创建jdbcTemplate对象 注入数据库连接池-->
34     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
35         <property name="dataSource" ref="c3p0"></property>
36     </bean>
37     
38 </beans>
 1 package org.test;
 2 
 3 import org.junit.Test;
 4 import org.service.Service;
 5 import org.springframework.context.ApplicationContext;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 public class TestSalary {
 9     @Test
10     public void testsalary(){
11         ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
12         Service s=(Service)ac.getBean("service");
13         s.changeSalary();
14     }
15 }

程序运行结果:小王向小马转账2000,数据库中的数据得到了更新

以上代码没有使用事务,但是如果在转账过程中,即

1     public void changeSalary(){
2         System.out.println("开始转账。。。。。。。。");
3         this.dao.lessSalary();

        A:此处发生错误

4         this.dao.moreSalary();
5         System.out.println("转账成功。。。。。。。。。。。");
6     }

函数中A处出现错误,就会造成数据的不一致性,即小王的salary减少,小马的salary没有得到增加

1     public void changeSalary(){
2         System.out.println("开始转账。。。。。。。。");
3         this.dao.lessSalary();
4         int t=10/0;//模拟发生异常
5         this.dao.moreSalary();
6         System.out.println("转账成功。。。。。。。。。。。");
7     }

二.使用Spring框架中的事务机制进行处理(其他地方代码不需要改变,只需要在配置文件中增加事务处理,这就是AOP的魅力)

 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:context="http://www.springframework.org/schema/context"
 5     xmlns:aop="http://www.springframework.org/schema/aop"
 6     xmlns:tx="http://www.springframework.org/schema/tx"
 7     xsi:schemaLocation="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="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
17         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
18         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/account"></property>
19         <property name="user" value="root"></property>
20         <property name="password" value="jay571018"></property>
21     </bean>
22     
23     <!-- 创建dao对象  注入jdbcTemplate-->
24     <bean id="dao" class="org.dao.Dao">
25         <property name="jdbcTemplate" ref="jdbcTemplate"></property>
26     </bean>
27     
28     <!-- 创建service对象  注入dao-->
29     <bean id="service" class="org.service.Service">
30         <property name="dao" ref="dao"></property>
31     </bean>
32     
33     <!-- 创建jdbcTemplate对象 注入数据库连接池-->
34     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
35         <property name="dataSource" ref="c3p0"></property>
36     </bean>
37     
38     <!-- 配置事务管理器 -->
39     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
40         <!-- 注入数据源 ,即上面的c3p0对象 -->
41         <property name="dataSource" ref="c3p0"></property>
42     </bean>
43     
44     <!-- 配置事务增强 ,指定使用的事务管理器,即上面配置的transactionManager-->
45     <tx:advice id="txadvice" transaction-manager="transactionManager">
46         <!-- 设置需要进行事务操作的方法  的匹配规则  本程序中对changeSalary()方法进行事务处理(change*包括changeSalary)-->
47         <tx:attributes>    
48             <tx:method name="changeSalary"/>
49         </tx:attributes>
50     </tx:advice>
51     
52     <!-- 配置切面,把增强用到具体方法上面的过程 -->
53     <aop:config>
54         <!-- 配置切入点 -->
55         <aop:pointcut expression="execution(* org.service.Service.*(..))" id="p1"/>
56         <!--指定使用的增强以及应用的切入点-->
57         <aop:advisor advice-ref="txadvice" pointcut-ref="p1"/>
58     </aop:config>
59     
60 </beans>

这样即使在A处发生了异常,通过事务的回滚机制,数据仍然保持一致性

所以事务处理在数据库访问中的作用显而易见。

三.使用注解方式实现事务管理

只需在service类上面标识注解,配置文件中开启注解扫描:

 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:context="http://www.springframework.org/schema/context"
 5     xmlns:aop="http://www.springframework.org/schema/aop"
 6     xmlns:tx="http://www.springframework.org/schema/tx"
 7     xsi:schemaLocation="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="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
17         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
18         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/account"></property>
19         <property name="user" value="root"></property>
20         <property name="password" value="jay571018"></property>
21     </bean>
22     
23     <!-- 创建dao对象  注入jdbcTemplate-->
24     <bean id="dao" class="org.dao.Dao">
25         <property name="jdbcTemplate" ref="jdbcTemplate"></property>
26     </bean>
27     
28     <!-- 创建service对象  注入dao-->
29     <bean id="service" class="org.service.Service">
30         <property name="dao" ref="dao"></property>
31     </bean>
32     
33     <!-- 创建jdbcTemplate对象 注入数据库连接池-->
34     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
35         <property name="dataSource" ref="c3p0"></property>
36     </bean>
37     
38     <!-- 配置事务管理器 -->
39     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
40         <!-- 注入数据源 ,即上面的c3p0对象 -->
41         <property name="dataSource" ref="c3p0"></property>
42     </bean>
43     
44     <!-- 开启注解扫描  指定事务管理器-->
45     <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
46     
47     <!-- 在需要使用事务的类上边标注注解 -->
48     
49     
50 </beans>

 1 package org.service;
 2 
 3 import org.dao.Dao;
 4 import org.springframework.transaction.annotation.Transactional;
 5 @Transactional //对该注解标识的类中的所有方法都加上注解
 6 public class Service {
 7     private Dao dao;
 8 
 9     public void setDao(Dao dao) {
10         this.dao = dao;
11     }
12     public void changeSalary(){
13         System.out.println("开始转账。。。。。。。。");
14         this.dao.lessSalary();
15         //int t=10/0;//模拟发生异常
16         this.dao.moreSalary();
17         System.out.println("转账成功。。。。。。。。。。。");
18     }
19 }

 

其他程序不变,同样实现了事务管理功能。

 

------------------------------

欢迎大家转载,但请注明原创链接:http://www.cnblogs.com/Joke-Jay/p/6505949.html

 

以上是关于Spring事务管理的主要内容,如果未能解决你的问题,请参考以下文章

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

Spring boot:thymeleaf 没有正确渲染片段

What's the difference between @Component, @Repository & @Service annotations in Spring?(代码片段

spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段

Spring Rest 文档。片段生成时 UTF-8 中间字节无效 [重复]

使用 Git 来管理 Xcode 中的代码片段