目录:
- 1.Spring事务管理 “含义”
- 2.Spring事务管理的 三个“核心接口” :
- 2.1 PlatformTransactionManager 接口
- PlatformTransactionManager接口 (3个“事务操作方法”)
- PlatformTransactionManager接口的 “实现类”
- 2.2 TransactionDefinition 接口
- 2.3 TransactionStatus 接口
- 3.Spring事务管理的方式 (两种)
- 3.1 声明式事务管理 (常用)
- 基于 XML方式的声明式事务
- 基于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知识点所需的依赖Junit单元测试所需的依赖
maven仓库网址(可自行按需下载)
第二步、创建Student类、StudentDao接口、StudentDaoImpl实现类,在接口中添加“转账方法”。Student.java
package 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
package com.myh.tx; import java.util.List; public interface StudentDao { //接口 /* 转账方法 outUser : 汇款人 inUser : 收款人 */ public void transfer(String outUser, String inUser, Double money); }
StudentDaoImpl.java
package 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 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 和context 3个命名空间(从配置数据源到声明事务管理器的部分都没有变化),然后定义了id 为 PlatormTransactionManager 的 事务管理器,接下来通过编写的通知来声明事务,最后通过声明AOP的方式让Spring自动生成代理。
第四步、创建事务管理的“测试类” : TransactionTest.java
package 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 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),和 注册 “事务注解驱动”。
<!-- 以下为基于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.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 (接口)
package com.myh.tx.annotation; public interface StudentDao { //接口 /* 转账方法 outUser : 汇款人 inUser : 收款人 */ public void transfer(String outUser, String inUser, Double money); }
StudentDao.java (实现类)
package 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 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 (测试类)
package 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("转账成功!!!"); //如果这一过程中报错的话,是会通过“事务管理”的知识点进行回滚的,不会造成数据错乱。 } }
测试类的效果是 :
当代码不报错时,自然能正常转账,但当代码报错时,程序会自动进行 “事务管理”,进行回滚,不会让数据发送错乱。