javaEE简单示例——基于注解的事务管理
简单介绍:
在之前,我们介绍了基于XML配置文件的配置方式,这种方式对于程序员来说还是比较繁琐了,我们这次来介绍一个更简单的方式来配置事务管理,那就是基于注解的事务管理。
接下来我们来开始介绍基于注解的事务管理。 首先我们要知道,注解的出现就是让我们更快捷方便的编写我们的代码,所以注解的使用是非常简单的 我们只需要记住一个注解就是@Transactional注解,这个注解就相当于是tx:advice标签,这个注解可以配置我们事务的相关配置,比如使用何种的事务管理器,传播行为以及隔离级别等信息
这个注解可以写在类上,写在方法上,位置不同它的含义也不相同,当这个注解写在类上的时候,表示这个类的所有的公共方法 都会使用事务管理,如果是写在方法上,则表示只有这个方法会使用事务管理。如果连个位置同时出现了该注解,则方法的注解会将 类中的注解给屏蔽掉,也就是之后写在方法上的注解会起作用
使用方法:
@Transactional的常用属性:
value:配置使用何种的事务管理器
propagation:配置事务的传播行为
isolation:配置事务的隔离级别
使用注解时,我们可以删掉之前我们写的事务管理的配置切片和事务管理器的部分代码,同时我们要添加事务的注解驱动
<tx:annotation-driven transaction-manager="transactionManager"/>
叫做tx:annotation-driven,在这个元素中,有一个属性叫做transaction_manager,这个属性用于指定我们使用的 事务管理器,比起在注解中配置事务管理器,我们更倾向于在这里配置。
// 模拟一个转账的事务,在Java中,事务的封装是通过方法来完成的,即多条SQL语句放在同一个方法中,这个方法就成为了一个事务
// 配置基于注解的事务管理
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,readOnly = false)
public void Transfer(String payer , String payee , int money){
// 定义数据的调整的SQL语句
String SQL1 = "update user set money = money - ? where name = ?";
String SQL2 = "update user set money = money + ? where name = ?";
this.jdbcTemplate.update(SQL1,money,payer);
// 模拟在执行事务的时候,如果中间有一个异常发生了
int i = 1/0;
this.jdbcTemplate.update(SQL2,money,payee);
}
在了解这些之后,我们就可以根据我们之前列出的步骤来配置基于注解的事务管理,我们再来展示一下完整的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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:bean="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
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">
<!-- 创建数据源对象-->
<bean id="dateSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="@gaoyang1"/>
</bean>
<!-- 创建模板类对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dateSource"/>
</bean>
<!-- 创建自定义数据库操作类的对象,最终我们只需要或者这个对象就可以了-->
<bean id="manipulatingDatabase" class="Semester_4.SpringJDBC.TransactionManagement.ByConfigurationFile.ManipulatingDatabase">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<!-- 创建结果集映射类的bean-->
<bean id="user" class="Semester_4.SpringJDBC.TransactionManagement.ByConfigurationFile.user"/>
<!-- 创建事务管理类的bean-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 因为这个类需要依赖与数据源,所以将数据源对象使用依赖注入的方式进行赋值-->
<property name="dataSource" ref="dateSource"/>
</bean>
// 配置事务注解驱动,他会加载事务管理器,并且扫描类中出现的与事务管理有关的注解
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
代码实现:
在完成了配置之后,我们就创建测试类进行事务管理的测试:
package Semester_4.SpringJDBC.TransactionManagement.ByNote;
import Semester_4.SpringJDBC.TransactionManagement.ByNote.ManipulatingDatabase;
import Semester_4.SpringJDBC.TransactionManagement.ByNote.user;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import java.util.List;
public class test {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("TeansactionManager.xml");
ManipulatingDatabase md = (ManipulatingDatabase)ac.getBean("manipulatingDatabase");
RowMapper<user> mapper = new BeanPropertyRowMapper<>(user.class);
System.out.println("更改之前的数据:");
List<user> queryBefore = md.getJdbcTemplate().query("select * from user", mapper);
for(user u : queryBefore){
System.out.println(u.toString());
}
md.Transfer("张三","李四",100);
List<user> queryAfter = md.getJdbcTemplate().query("select * from user", mapper);
System.out.println("更改之后的数据:");
for(user u : queryAfter){
System.out.println(u.toString());
}
}
}
运行结果:
方法报错,终止,我们来看数据库中的数据:
数据没有变化,数据管理成功!
注意点:
在这一章节的注意点就是我们要明确这个注解是写在什么位置的,以及写在不同的位置会导致什么样的结果,然后就是别忘了在Bean管理XML配置文件中添加事务管理器的注解驱动,这些步骤一个也不能少