文章目录
- 一、Spring中的template
- 1.1 作用
- 1.2 所需的依赖
- 二、spring中的事务
- 2.1 概述
- 2.2 spring中的事务级别
- 2.3 事务的传播行为
- 2.4 超时时间
- 2.5 是否是只读事务
- 2.6 事务状态
- 三、spring中事务测试
- 3.1 spring中基于xml的声明式事务的配置
- 3.2 spring中基于注解的声明式事务的配置步骤
- 3.3 纯注解的事务配置
- 3.4 编程式事务
- 四、事务测试
- 4.1 事务
- 4.2 传播行为
- 4.4.1 required
- 4.4.2 required_new
- 4.4.3 never
- 4.4.4 NOT_SUPPORTED
- 4.4.5 Propagation.NESTED
- 4.4.6 Propagation.SUPPORTS
一、Spring中的template
1.1 作用
操作数据库的,实现对数据库的增删改查
1.2 所需的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
二、spring中的事务
2.1 概述
spring事务是基于aop的,它可以使用编程的方式实现,也可以使用事务的方式实现。
TransactionDefinition类中包含了对事务的一些定义
2.2 spring中的事务级别
- 作用是规定事务提交并发访问时的处理态度
int ISOLATION_DEFAULT = -1;
可以读取未提交的数据
int ISOLATION_READ_UNCOMMITTED = 1;
只能读取已经提交的数据,解决脏读问题
int ISOLATION_READ_COMMITTED = 2;
是否读取其他事务提交修改后的数据,解决不可重复读问题
int ISOLATION_REPEATABLE_READ = 4;
是否读取其他事务提交添加后的数据,解决幻读问题
int ISOLATION_SERIALIZABLE = 8;
2.3 事务的传播行为
int PROPAGATION_REQUIRED = 0;
如果当前没有事务则新建一个事务,如果有事务,则加入事务。(默认选这个)
int PROPAGATION_SUPPORTS = 1;
支持当前事务,如果没有事务,则以非事务方式进行
int PROPAGATION_MANDATORY = 2;
使用当前事务,如果没有事务,则抛出异常
int PROPAGATION_REQUIRES_NEW = 3;
新建事务
int PROPAGATION_NOT_SUPPORTED = 4;
以非事务方式进行
int PROPAGATION_NEVER = 5;
以非事务方式进行,如果当前存在事务,则把当前事务挂起
int PROPAGATION_NESTED = 6;
当前有事务,则嵌套运行,无事务,按照PROPAGATION_REQUIRED方式进行
2.4 超时时间
- 默认没有超时限制
int TIMEOUT_DEFAULT = -1;
2.5 是否是只读事务
- 默认是false,建议查询时设置为只读
default boolean isReadOnly() {
return false;
}
2.6 事务状态
描述了事务在某个时间点上的状态信息
boolean isNewTransaction();
//是否为新事务
void setRollbackOnly();
//设置回滚点
boolean isRollbackOnly();
//是否回滚
boolean isCompleted();
//是否完成
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
boolean hasSavepoint();
//是否有回滚点
void flush();
//刷新事务
}
三、spring中事务测试
3.1 spring中基于xml的声明式事务的配置
- 配置事务管理器
- 配置事务的通知
- 配置aop中的通用切入点表达式
- 建立事务通知和切入点表达式的对应关系
- 配置事务的属性
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置业务层-->
<!-- 配置账户持久层-->
<!-- 配置数据源-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/student"></property>
<property name="username" value="ybx"></property>
<property name="password" value="111111"></property>
</bean>
<!-- 配置事务的管理器-->
<!-- ref就是上面配置的datasource -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>
<!-- 配置事务的通知-->
<!-- transaction-manager 给事务通知提供一个事务管理器的应用
id 事务通知的唯一标识-->
<tx:advice id="txAAA" transaction-manager="transactionManager">
<!-- 配置事务的属性-->
<!-- rollback-for 指定一个异常,当该异常产生时,事务回滚,产生其他异常,事务不回滚,没有默认值,表示任何异常都回滚
propagation 事务的传播行为
no-rollback-for 指定一个异常,当该异常发生时,事物不回滚,没有默认值,表示任何异常都回滚
isolation 事务的隔离级别
read-only 设置为只读-->
<tx:attributes>
<!-- name:对方法名称的匹配-->
<tx:method name="*" propagation="REQUIRED" read-only="false"></tx:method>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
</tx:attributes>
</tx:advice>
<!-- 配置aop的通用切入点表达式-->
<aop:config>
<aop:pointcut id="aopPoint" expression="execution(public * com.example.demo.Service.stuService.*(..))"/>
<!-- 建立切入点表达式和事务通知的对应关系-->
<aop:advisor advice-ref="txAAA" pointcut-ref="aopPoint"></aop:advisor>
</aop:config>
</beans>
简单的说就是配置事务在serveice中哪些方法应用
3.2 spring中基于注解的声明式事务的配置步骤
注意:只有部分配置,配置不全<?xml version="1.0" encoding="UTF-8"?>
<tx:annotation-driven transaction-manager=“transactionManager”
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置业务层-->
<!-- 配置账户持久层-->
<!-- 配置数据源-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/student"></property>
<property name="username" value="ybx"></property>
<property name="password" value="111111"></property>
</bean>
<!-- spring中基于注解的声明式事务的配置步骤
1. 配置事务管理器
2.开启spring对注解事务的支持
3.在需要事务支持的地方使用@Transactional注解
-->
<!-- 配置事务的管理器-->
<!-- ref就是上面配置的datasource -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>
<!-- 开启spring对注解事务的支持-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>
3.3 纯注解的事务配置
- 需要的配置类
@Configuration
@ComponentScan(basePackages = "com.example.demo")
@EnableTransactionManagement
public class txConfig {
@Bean(value = "datasource")
public DataSource getInstance1(){
DriverManagerDataSource mysqlDataSource = new DriverManagerDataSource();
mysqlDataSource.setUrl("jdbc:mysql://localhost:3306/student");
mysqlDataSource.setPassword("510363");
mysqlDataSource.setUsername("ybx");
mysqlDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
System.out.println(mysqlDataSource.getUrl() + " " + mysqlDataSource.getUsername());
return mysqlDataSource;
}
@Bean
public PlatformTransactionManager getInstance(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}
3.4 编程式事务
手动的将事务的内容编程到我们的代码中,比较麻烦。
四、事务测试
4.1 事务
4.2 传播行为
4.4.1 required
- 没有事务,则新建事务执行,有则使用的事务。
- 子出现异常,就算父捕获也会整体回滚
4.4.2 required_new
- 无论外面是否有事务,都会创建新事务执行,每个事务都会单独执行,互不干扰。
- 里外都是required_new,则哪里发生异常,后面的事务就不会再执行。
4.4.3 never
- 以非事务进行,存在事务则抛出异常
4.4.4 NOT_SUPPORTED
- 外层的传播行为是require
- 嵌套方法B的传播行为NOT_SUPPORTED,为有事务则挂起事务,以非事务进行,存在异常,异常前的代码可以执行,异常后的代码不能执行,外层的事务遇到异常会回滚
4.4.5 Propagation.NESTED
- 存在事务则新建事务嵌套运行,不存在事务则和required_new一致。
- 存在事务,子发生异常,父如果捕捉子的异常,则子回滚,父不会回滚。父正常提交。
4.4.6 Propagation.SUPPORTS
- 存在事务则加入事务,没有事务则以非事务进行。