目录:
-
- [1.Spring事务管理 "含义"](#1.Spring事务管理 “含义”)
- [2.Spring事务管理的 三个"核心接口" :](#2.Spring事务管理的 三个“核心接口” :)
-
-
- [2.1 PlatformTransactionManager 接口](#2.1 PlatformTransactionManager 接口)
-
- PlatformTransactionManager接口 (3个"事务操作方法")
- [PlatformTransactionManager接口的 "实现类"](#PlatformTransactionManager接口的 “实现类”)
- [2.2 TransactionDefinition 接口](#2.2 TransactionDefinition 接口)
- [2.3 TransactionStatus 接口](#2.3 TransactionStatus 接口)
-
- 3.Spring事务管理的方式 (两种)
-
-
- [3.1 声明式事务管理 (常用)](#3.1 声明式事务管理 (常用))
-
- [基于 XML方式的声明式事务](#基于 XML方式的声明式事务)
- [基于Annotation (注解) 方式的声明式事务 (常用)](#基于Annotation (注解) 方式的声明式事务 (常用))
-
作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!
该文章参考学习教材 为:
《Java EE企业级应用开发教程 (Spring + Spring MVC +MyBatis)》 黑马程序员 / 编著文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章
文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!
(侵权教材方可联系我,进行删除,如果雷同,纯属巧合)
1.Spring事务管理 "含义"
- Spring JDBC 可以用来操作数据库 ,在实际开发中,操作数据库时 还会涉及 事务管理问题,为此Spring 提供了 专门用于事务处理 的 API。
- Spring 的 事务管理 简化了传统的事务管理流程,并且在一定程度上减少了开发者 的工作量。
- 要想 使用Spring事务功能 ,要 导入 spring-tx.Jar 这个包 。
Spring事务管理的JAR包
jar包 / maven( 依赖 ) 下载( 可自行按需下载JAR )
2.Spring事务管理的 三个"核心接口" :
spring-tx.jar 这个jar包是Spring 提供的用于事务管理 的依赖包。
在该jar包下的org.springframework.transaction 包中,可以看到 三个主要的接口 ( 三个核心接口 ) :
PlatformTransactionManager (接口) 、TransactionDefinition (接口)、TransactionStatus (接口)
具体讲解如下 :
2.1 PlatformTransactionManager 接口
PlatformTransactionManager接口 (3个"事务操作方法")
PlatformTransactionManager接口 是Spring提供的平台事务管理器,主要用于管理事务 。该接口中提供 了 3个事务操作 的方法,具体如下。
① TransactionStatus getTransaction ( TransactionDefinition definition ) :
用于 获取事务状态信息。
② void commit ( TransactionStatus status ) : 用于提交事务。
③ void rollback ( TransactionStatus status ) : 用于回滚事务。ps :
(在上面的3个方法 中,getTransaction ( TransactionDefinition definitin )方法会根据 TransactionDefinition 参数返回 一个 TransactionStatus对象 ,TransactionStatus 对象就表示一个事务 ,它被关联在当前执行的线程上。)
PlatormTransactionManager接口 只是代表事务管理 的接口 ,,它并不知道底层是如何管务 的,它只 提供三个业务管理的方法 ,事务管理过程 由于它的实现类完成。
(当底层 采用不同 的持久层技术 时,系统只需使用不同 的PlatformTransactionManager 实现类即可。
PlatormTransactionManager接口 常见的实现类 有 :
① org.springframework.jdbc.datasource.DataSourceTransactionManager :用于配置 JDBC 数据源 的事务管理器。
② org.springframework orm.hibemate4 .HiberateTransationManager : 用于 配置Hiber 的事务管理器。
③ org.springframework.transaction.jta .JtaTransactionManager :用于配置 全局事理器。
PlatformTransactionManager接口的 "实现类"
PlatormTransactionManager接口 只是代表事务管理 的接口 ,,它并不知道底层是如何管务 的,它只 提供三个业务管理的方法 ,事务管理过程 由于它的实现类完成。
(当底层 采用不同 的持久层技术 时,系统只需使用不同 的PlatformTransactionManager 实现类即可。
PlatormTransactionManager接口 常见的实现类 有 :
① org.springframework.jdbc.datasource.DataSourceTransactionManager :用于配置 JDBC 数据源 的事务管理器。ps :
DataSourceTransactionManager 依赖于 数据源 ,要在其的property属性 中添加 dataSource.② org.springframework orm.hibemate4 .HiberateTransationManager : 用于 配置Hiber 的事务管理器。
③ org.springframework.transaction.jta .JtaTransactionManager :用于配置 全局事理器。
2.2 TransactionDefinition 接口
TransactionDefinition 接口 是 事务定义 (描述 ) 的 对象 ,该对象中 定义了事务规则。并提供了 获取事务相关信息 的方法。(通过该接口提供 的 方法 能获取"事务的信息")
TransactionDefinition 接口提供 的 能 "获取事务相关信息" 的方法 如下 :
String getName( ) :获取 事务对象名称。
int getlsolationLevel( ) : 获取事务 的 隔离级别。
int getPropagationBehavior( ) : 获取事务 的 传播行为。
int getTimeout( ) : 获取事务 的 超时时间。
boolean isReadOnly( ) : 获取 事务是否只读。
ps :
上述方法中,事务的传播行为 是指在同一个方法 中,不同操作前后所使用的事务 ,传播行为很多种。
在事务管理 过程中,传播行为 可以控制是否需要创建事务 以及如何创建事务 ,通常情况下,数据的查询 不会影响原数据的改变,所以不需要进行事务管理,而对于数据的插入、更新和删除操作 ,必须进行事务管理 。如果没有指定 事务的传播行为,Spring 默认传播行为 是REQUIRED。
2.3 TransactionStatus 接口
- TransactionStatus接口 是 事务的状态,它描述了某一时间点上事务 的状态信息。
- 该接口中包含6个方法 ,具体如下。
- void flush( ) : 刷新事务。
- boolean hasSavepoint( ) : 获取 是否存在保存点。
- boolean isCompleted() : 获 取事务是否完成。
- boolean isNewTransaction( ) : 获取 是否是新事务。
- boolean isRollbackOnly( ):获取 是否回滚。
- void setRollbackOnly( ): 设置事务回滚。
3.Spring事务管理的方式 (两种)
Spring 中的 事务管理 分为两种方式 :
① 编程式事务管理
② 声明式事务管理 (常用 ) ,下面主要讲的内容也是 "声明式事务管理"。
编程式事务管理 : 是通过编 写代码实现 的事务管理,包括定义事务的开始 、正常执行后的事务提交 和 异常时 的事务回滚。
声明式事务管理: 是通过 AOP技术实现 的事务管理,其主要思想是将事务管理作为一个'切面"代码单独编写 ,然后通过AOP技术将 事务管理的 "切面" 代码织入 到业务目标类中。
声明式事务管理 最大的优点 在于开发者无须 通过编程的方式来管理事务,只需在配置文件中 进行相关的事务规则声明 ,就可以将事务规则 应用到业务逻辑 中。这使得开发人员可以更加专注于核心业务逻辑代码的编写 ,在一定程度上减少了 工作量,提高了 开发效率,所以在实际开发中,通常都推荐 使用声明式事务管理。
3.1 声明式事务管理 (常用)
- Spring的 声明式事务管理 可以通过两种方式 来实现,
一、基于XML的方式 ( 基于 XML方式 的声明式事务 ) ---通过xml配置文件 的方式来实现"事务管理"的功能。
二、基于Annotation (注解)的方式 (常用 )---通过在代码中添加 "注解"的方式来实现"事务管理"的功能。
基于 XML方式的声明式事务
基于XML方式的声明式事务管理 是通过在配置文件 中配置事务规则 的相关声明来实现的。
Spring2.0以后 ,提供了tx命名空间 来配置事务 ,tx命名空间 下提供了 <tx:advice>元素 来配置事务的通知 (增强处理) 。 当使用 <tx:advice>元素配置了事务的增强处理后 ,就可以通过编写的AOP配置 ,让Spring自动对目标生成代理
(自动生成代理 目的是 : 让事务对每个"报错/方法"生效)。
配置配置<tx:advice>元素时,通常需要指定 id 和 transaction-manager 属性,其中id属性 是配置文件中的唯一标识 , transaction-manager 属性 用于指定事务管理器。
除此之外,还需要配置 <tx:atributes>子元素,该子元素 可通过配置多个 <tx:method>子元素 来配置执行事务的细节 。
<tx:advice>元素 及其子元素如下图所示:(配置<tx:advice>元素的重点的配置<tx:method>元素)
<tx:method>元素的属性 :
属性名称 描述 name 该属性为必选属性,它指定了与事务属性相关的方法名。其属性值支持使用通配符。 : 如'get*'、'handle*'、 '*Order'等 如:<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> propagation 用于指定事务的传播行为 ,默认值为 REQUIRED。 isolation 该属性用于指定事务的隔离级别 : READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ 和 SERIALIZABLE,其默认值为DEFAULT。 read-only 该属性用于 指定事务是否只读,其默认值为 false。 timeout 该属性用于 指定事务超时的时间,其 -1,即永不超时。 rollback-for 该属性用于 指定触发"事务回滚" 的 异常类,在指定多个异常类时,异常类之间以英文逗号分隔。 no-rolback-for 该属性用于 指定 "不触发" 事务回滚 的异常类,在指定多个异常类时,异常类之间以英文逗号分隔。 基于 XML方式 的声明式事务 的"例子" 如下 :
第一步、导入依赖 :
①Spring框架的基本核心依赖
②Spring JDBC要导入的依赖 ③Spring事务的依赖④事务管理 中要用到AOP 的知识点所需 的依赖 ⑤Junit4单元测试 的依赖
获取spring框架基本核心jar包
获取Spring JDBC要导入的依赖
Spring事务的依赖
事务管理中要用到的AOP知识点所需的依赖第二步、创建Student类 、StudentDao接口 、StudentDaoImpl实现类 ,在接口中添加"转账方法 "。Student.java
javapackage com.myh.tx; public class Student { private Integer id; //学生id private String username; //用户名 private String hobby; private Double money; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getHobby() { return hobby; } public void setHobby(String hobby) { this.hobby = hobby; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return "Student{" + "id=" + id + ", username='" + username + '\'' + ", hobby='" + hobby + '\'' + ", money=" + money + '}'; } }
StudentDao.java
javapackage com.myh.tx; import java.util.List; public interface StudentDao { //接口 /* 转账方法 outUser : 汇款人 inUser : 收款人 */ public void transfer(String outUser, String inUser, Double money); }
StudentDaoImpl.java
javapackage com.myh.tx; import org.springframework.jdbc.core.JdbcTemplate; import java.util.List; public class StudentDaoImpl implements StudentDao { //操作数据库的过程是通过 JDBC核心类:JdbcTemplate 的方法来进行的 //注入JdbcTemplate类 private JdbcTemplate jdbcTemplate; //配置文件的对应的property属性给jdbcTemplate赋值 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** 转账方法 outUser : 汇款人 inUser : 收款人 */ /* 在两个操作之间,添加了一行代码"inti= 1/0:;"来模拟系统运行时的突发性问题。如果没有事务控制,那么在转账操作执行后,收款用户的余额会增加, 而汇款用户的余额会因为系统出现问题而不变,这显然是有问题的; -----添加 "事务管理" 则可解决这个问题 */ @Override public void transfer(String outUser, String inUser, Double money) { //收款时,"收款学生用户" 的金额 = 现有金额 + 所汇金额 //sql语句修改student表的money数据 String sql = "update student set money = money + ? where username = ?"; this.jdbcTemplate.update(sql,money, inUser); // inUser : 收款人 //模拟系统运行时突发性情况 //int i = 1 / 0; //因为此处报错了,如果没有添加"事务管理",那么资金就会错乱了---要进行"事务管理"操作 //汇款时,汇款用户的余额 = 现有余额 - 所汇余额 this.jdbcTemplate.update("update student set money = money - ? where username = ?", money, outUser);//outUser : 汇款人 } }
第三步、在applicationContext.xml 中 ①编写事务通知 ② 配置"通知器 " (该通知器 可为 "事务管理 " 服务 )
ps :
在<aop:config>中配置<aop:advisor> : 通知器 ,将"切入点 " 和 tx:advice通知 进行整合 。
applicationContext.xml
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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 通过JDBC来连接数据库 --> <!-- 1.配置数据源(dataSource) --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/spring"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!-- 2.配置JDBC的核心类: JdbcTemplate (JDBC模板类) --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 3. ①将StudentDaoImpl加入到IOC容器中 ②将JdbcTemplate注入到StudentDaoImpl,让其进行调用核心类中的方法来操作数据库 --> <bean id="studentDao" class="com.myh.tx.StudentDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean> <!-- 通过基于XML的声明式"事务管理"来为代码添加 "事务"功能 --> <!-- 4.事务管理器 (PlatormTransactionManager : 平台事务管理器) --> <bean id="PlatormTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 配置"平台事务管理器"的 "数据源" --> <property name="dataSource" ref="dataSource"/> </bean> <!-- 5.编写通知 : 对事务进行增强(通知) ,需要编写对切入点和具体执行事务细节 --> <tx:advice id="txAdvice" transaction-manager="PlatormTransactionManager"> <tx:attributes> <!-- name : 指定"事务"对哪些方法起作用。 * 表示对所有方法起作用 --> <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> </tx:attributes> </tx:advice> <!-- 6.编写aop,让spring自动对目标生成代理( 让事务对每个"报错/方法"生效),小使用AspectJ的表达式 --> <aop:config> <!-- 配置切入点 (切入点即为要被增强处理的"方法") --> <aop:pointcut id="txPointCut" expression="execution(* com.myh.tx.*.*(..))"/> <!-- (属于AspectJ中的知识点)配置"通知器" : 将"切入点" 和 "事务的通知"整合,来让事务功能生效 --> <!-- 配置"通知器" : AspectJ中的知识点为"事务管理服务" --> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config> </beans>
在上述配置文件 中,首先启用了Spring 配置文件 的aop 、tx 和conte xt 3个命名空间(从配置数据源到声明事务管理器的部分都没有变化),然后定义了id 为 PlatormTransactionManager 的 事务管理器 ,接下来通过编写 的通知 来声明事务 ,最后通过声明AOP的方式 让Spring自动生成代理。
第四步、创建事务管理的"测试类" : TransactionTest.java
javapackage com.myh.tx; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TransactionTest { //事务管理的"测试类" @Test //单元测试 public void XmlTransactionTest() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/myh/tx/applicationContext.xml"); StudentDao studentDao = (StudentDao)applicationContext.getBean("studentDao"); studentDao.transfer("小红", "小明", 50.0); //输出提示信息 System.out.println("转账成功!!!"); //如果这一过程中报错的话,是会通过"事务管理"的知识点进行回滚的,不会造成数据错乱。 } }
运行结果 描述 :
如果没报错 ,则代码正常运行 ,数据正常变化。如果代码报错 ,则会进行回滚 ,不会造成数据错乱。
基于Annotation (注解) 方式的声明式事务 (常用)
Spring 的声明式事务管理 还可以通过 Annotation (注解)的方式 来实现 (即通过在代码中 添加 "注解 " 的方式来完成 "事务管理")。
基于Annotation (注解) 方式的声明式事务 要完成 的步骤 :
第一步、先在配置文件 中 配置 好 Spring JDBC。
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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 通过JDBC来连接数据库 --> <!-- 1.配置数据源(dataSource) --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/spring"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!-- 2.配置JDBC的核心类: JdbcTemplate (JDBC模板类) --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 3. ①将StudentDaoImpl加入到IOC容器中 ②将JdbcTemplate注入到StudentDaoImpl,让其进行调用核心类中的方法来操作数据库 --> <bean id="studentDao" class="com.myh.tx.xml.StudentDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean> </beans>
第二步、在配置文件 中 配置平台事务管理器 ( 其中要用到Spring JDBC ),和 注册 "事务注解驱动"。
xml<!-- 以下为基于Annotation方式是声明式事务 : 需要①配置"平台事务管理器" ②注册"事务注解驱动" ③(在实际的代码中添加注解来获取"事务管理的功能") --> <!-- 只需在配置文件中 注册"事务注解驱动" --> <!-- 4.事务管理器 (PlatormTransactionManager : 平台事务管理器) --> <bean id="PlatormTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 配置"平台事务管理器"的 "数据源" --> <property name="dataSource" ref="dataSource"/> </bean> <!-- 5.注册"事务注解驱动" : 让代码中添加"注解"就能有"事务管理"的效果 --> <tx:annotation-driven transaction-manager="PlatormTransactionManager"/>
第三步、在需要使用事务 的Spring Bean类 或者 Bean类 的方法上 添加注解 @Transactional。
将注解 添加在Bean类 上,则表示事务的设置对整个Bean类的所有方法都起作用 。添加在Bean类 中的某个方法 上,则表示事务的设置只对该方法有效。
使用 @Transactional注解 时,可以通过其参数配置事务详情。
@Transactional注解的参数及其描述 如下表所示 :
参数名称 描述 value 用于指定需要使用 的事务管理器,默认为"",value 的 别名 为transactionManage。 transactionManager 指定事务的 限定符值,可用于 确定目标事务管理器,匹配特定的限定值 (或者的name值),默认"",其 别名 为value。 isolation 用于指定别的 隔离级别,默认为Isolation.DEFAULT (即底层事务 的隔离级别级别) noRollbackFor 用于指定 遇到特定异常时强制不回滚事务。 noRollbackForClassName 用于指定遇到特定的多个异常 时强制不回滚事务 。其属性值可以指定多个异常。 propagation 用于指定事务的 传播行为,默认 为Propagation.REQUIRED。 read-only 用于指定事务是否只读,默认 为 falses。
参数名称 描述 rollbackFor 用于指定遇到特定异常 时强制回滚事务。 rollbackForClassName 用于指定遇到特定的多个异常 时强制回滚事务。其属性值可以指定多个异常类名。 timeout 用于指定事务的超时时长 ,默认为TransactionDefinition .TIMEOUT _DEFAULT (即底层事务系统 的默认时间)。 ps :
在实际开发 中,事务的配置信息 通常是在Spring的配置文件中完成的 ,而在业务层类 使用 @Transactional注解 即可,不需要配置@Transactional注解 的属性。
例子如 :
例子如 :
Student.java
javapackage com.myh.tx.annotation; public class Student { private Integer id; //学生id private String username; //用户名 private String hobby; private Double money; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getHobby() { return hobby; } public void setHobby(String hobby) { this.hobby = hobby; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return "Student{" + "id=" + id + ", username='" + username + '\'' + ", hobby='" + hobby + '\'' + ", money=" + money + '}'; } }
StudentDao.java (接口)
javapackage com.myh.tx.annotation; public interface StudentDao { //接口 /* 转账方法 outUser : 汇款人 inUser : 收款人 */ public void transfer(String outUser, String inUser, Double money); }
StudentDao.java (实现类)
javapackage com.myh.tx.annotation; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.annotation.Transactional; public class StudentDaoImpl implements StudentDao { //操作数据库的过程是通过 JDBC核心类:JdbcTemplate 的方法来进行的 //注入JdbcTemplate类 private JdbcTemplate jdbcTemplate; //配置文件的对应的property属性给jdbcTemplate赋值 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** 转账方法 outUser : 汇款人 inUser : 收款人 使用Spring事务的基于"Annotation(注解)"的方式来配置事务,通过注解即可让代码实现事务功能 在类或类的方法中添加 @Transactional 注解,还可按需配置其对应的"属性"。 */ @Transactional //此处添加注解,来为该方法开启"事务管理" @Override public void transfer(String outUser, String inUser, Double money) { //收款时,"收款学生用户" 的金额 = 现有金额 + 所汇金额 //sql语句修改student表的money数据 String sql = "update student set money = money + ? where username = ?"; this.jdbcTemplate.update(sql,money, inUser); // inUser : 收款人 //模拟系统运行时突发性情况 //int i = 1 / 0; //因为此处报错了,如果没有添加"事务管理",那么资金就会错乱了---要进行"事务管理"操作 //汇款时,汇款用户的余额 = 现有余额 - 所汇余额 this.jdbcTemplate.update("update student set money = money - ? where username = ?", money, outUser);//outUser : 汇款人 } }
上述类的 transfer( ) 方法中,添加了 @Transactional 注解 ,以此来为该方法开启 "事务管理"。
applicationContext.xml
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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 通过JDBC来连接数据库 --> <!-- 1.配置数据源(dataSource) --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/spring"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!-- 2.配置JDBC的核心类: JdbcTemplate (JDBC模板类) --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 3. ①将StudentDaoImpl加入到IOC容器中 ②将JdbcTemplate注入到StudentDaoImpl,让其进行调用核心类中的方法来操作数据库 --> <bean id="studentDao" class="com.myh.tx.xml.StudentDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean> <!-- 以下为基于Annotation方式是声明式事务 : 需要①配置"平台事务管理器" ②注册"事务注解驱动" ③(在实际的代码中添加注解来获取"事务管理的功能") --> <!-- 只需在配置文件中 注册"事务注解驱动" --> <!-- 4.事务管理器 (PlatormTransactionManager : 平台事务管理器) --> <bean id="PlatormTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 配置"平台事务管理器"的 "数据源" --> <property name="dataSource" ref="dataSource"/> </bean> <!-- 5.注册"事务注解驱动" : 让代码中添加"注解"就能有"事务管理"的效果 --> <tx:annotation-driven transaction-manager="PlatormTransactionManager"/> </beans>
TransactionTest.java (测试类)
javapackage com.myh.tx.annotation; import com.myh.tx.annotation.StudentDao; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TransactionTest { @Test public void annotationTest() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/myh/tx/annotation/applicationContext.xml"); StudentDao studentDao = (StudentDao)applicationContext.getBean("studentDao"); studentDao.transfer("小红", "小明", 50.0); //输出提示信息 System.out.println("转账成功!!!"); //如果这一过程中报错的话,是会通过"事务管理"的知识点进行回滚的,不会造成数据错乱。 } }
测试类的效果 是 :
当代码不报错 时,自然能正常转账 ,但当代码报错 时,程序会自动进行 "事务管理" ,进行回滚 ,不会让数据发送错乱。