bean.accountMoney();
}
}
就像上面的效果,这个时候就需要在service使用事务来处理了!!!事务在哪层都可以,但是我们最好是使用在业务逻辑service层的。
=============================================================================
通常我们事务是添加到Service层(业务逻辑层)。
在Spring 进行事务管理操作有两种方式:
-
编程式事务管理
-
声明式事务管理(使用最多)
编程式事务管理就是使用代码一步一步来进行事务的操作,这种方式很麻烦!并且代码非常冗余。
就像try-catch方法一样,来处理如下面情况:
声明式事务管理又分为基于注解方式(最常用)和基于xml配置文件方式。
而在Spring中进行声明式事务管理,底层使用的是AOP原理,很合理!AOP就是面向切面编程,在不改变源代码的情况下,可以增强代码功能,那么平时面试问到Spring中使用AOP的底层原理有哪些,就可以回到Spring的声明式事务管理了。
Spring事务管理API:
- 提供一个PlatformTransactionManager接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类。
PlatformTransactionManager接口的结构层次了解:
我们可以通过ctrl + H来查看结构类的层次。
======================================================================================
第一步:在Spring配置文件来配置事务管理器。
因为,刚刚上面说到,不同框架对应实现了PlatformTransactionManager的不同实现类。
这里说的事务管理器,听起来很高大尚,实际上就是在beans.xml文件中创建对应的实现类就可,就像下面id为transactionManager的bean标签内容。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:context=“http://www.springframework.org/schema/context”
xmlns:aop=“http://www.springframework.org/schema/aop”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package=“com.itholmes”/>
第二步:在Spring配置文件,开启事务注解。
- 1.在spring配置文件beans.xml中引入名称空间tx。
(这里的tx,就是我们之前导入的spring tx包。Spring-tx模块负责在spring框架中实现事务管理功能。以aop切面的方式将事务注入到业务代码中,并实现不同类型的事务管理器。)
xmlns:tx=“http://www.springframework.org/schema/tx”
xsi:schemaLocation="
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"
- 2.开启事务的注解,在配置文件beans.xml中开启事务注解。
<tx:annotation-driven transaction-manager=“transactionManager”></tx:annotation-driven>
完整版beans.xml效果如下:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:context=“http://www.springframework.org/schema/context”
xmlns:aop=“http://www.springframework.org/schema/aop”
xmlns:tx=“http://www.springframework.org/schema/tx”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.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">
<context:component-scan base-package=“com.itholmes”/>
<tx:annotation-driven transaction-manager=“transactionManager”></tx:annotation-driven>
第三步:在service类上面(或者service类里面方法上面) 添加事务注解。
-
@Transactional注解,既可以添加到类上面也可以添加到方法上面。
-
添加到类上面,那么这个类里面所有的方法都给他们添加事务。
-
添加到方法上面,那么仅仅是给这个方法添加事务。
package com.itholmes.service;
import com.itholmes.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class UserService {
//注入dao
@Autowired
private UserDao userDao;
//在service业务逻辑层中调用转账方法
public void accountMoney() {
//一旦设定了@Transactional注解下面的步骤会自动执行,因为是AOP切面编程原理。
//第一步:开启事务
//第二部:进行业务操作
//lucy转账100
userDao.reduceMoney();
//模拟异常,比如断电了,断网了等等。
int i = 1 / 0;
//mery收账100
userDao.addMoney();
//如果上面步骤都没有发生异常,则我们就要进行事务提交了。
//第三部:提交事务
//如果出现错误,出现异常。
//第四部:事务回滚
}
}
这样我们再通过test测试类来测试, 能否达到事务回滚的效果。
=====================================================================================
@Transactional,在这个注解里面可以配置事务相关参数。
idea中可以使用ctrl + p来查看参数。
事务参数中,我们常用的如下几种:
-
参数propagation:事务传播行为。
-
参数ioslation:事务隔离级别。
-
参数timeout:超时时间。
-
参数readOnly:是否只读。
-
参数rollbackFor:回滚。
-
参数noRollbackFor:不回滚。
参数propagation:事务传播行为。
- 多事务方法直接进行调用,这个过程中事务是如何进行管理的。
对于上面几个名词需要理解:
什么是事务方法?
对数据库表数据进行变化的操作就叫做事务方法,也就是查询的相关操作就是不是事务操作!
什么是事务传播行为?
事务传播行为大体分为下面几种情况:就是一个有事务的方法调用了一个没有事务的方法;一个没有事务的方法调用了一个有事务的方法;一个有事务的方法调用了一个也有事务的方法。这种过程就叫做事务传播行为。
事务的传播行为分为7种,图片如下:
事务的传播行为分为7种,但是最常用的是以下两种(重要,记住!):
(图片统一对照第一张)
-
REQUIRED(required , 也是默认的):
-
REQUIRED_NEW(required_new):
参数效果如下图:
事务的隔离级别,首先理解隔离两个字,其实所谓的隔离就是多个事物之间不会产生影响!
事务的特性之一就是隔离性,多事务操作之间不会产生影响。
如果事务不考虑隔离性会产生很多问题!例如:脏读,不可重复读,虚读(幻读)。
- 脏读:一个未提交事务读取到另一个未提交事务的数据。
(脏读是一个致命问题,已经影响到了我们期望的结果)
- 不可重复读:一个未提交的事务读取到了另一个提交的事务所修改的数据。
(不可重复度是一种现象,这个现象是允许产生的,只不过需要做一些统一操作等等,它本身不能算是一个问题。)
- 虚读(幻读):一个未提交事务读取到另一个提交事务添加的数据。
(和不可重复度差不多,只不多这里是添加了数据。)
因此,我们Spring中,通过设置事务隔离性ioslation ,来解决上面这些问题:
在mysql中,我们如果不设置隔离级别的话,默认是第三种级别 REPEATABLE READ 可重复读。
参数效果如下图:
参数timeout:超时时间。
这个就好理解了,就是事务开启后需要在一定时间内进行事务提交,不然就会回滚,意思就是超时了!
spring中timeout参数的默认值为 -1 ,就是不超时。
设置时间以秒为单位进行的。
参数readOnly:是否只读。
-
读:查询操作。
-
写:添加删除修改操作。
这里的读,意思就是查询操作了。
参数readOnly默认值一般为false,false表示可以查询,修改删除等操作。
设置为true,就只能进行读操作,也就是查询操作。
参数rollbackFor:回滚。
- 设置出现哪些异常进行事务回滚。
参数noRollbackFor:不回滚。
- 设置出现哪些一场不进行事务回滚。
这就很好理解了,出现哪些异常需要回滚,哪些异常不需要回滚的效果。
=======================================================================================
声明式事务管理,xml方式步骤如下:
-
第一步:配置事务管理器。
-
第二步:配置通知。
-
第三步:配置切入点和切面。
<beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:context=“http://www.springframework.org/schema/context”
xmlns:aop=“http://www.springframework.org/schema/aop”
xmlns:tx=“http://www.springframework.org/schema/tx”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.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
">
<context:component-scan base-package=“com.itholmes”/>
<tx:advice id=“txadvice”>
tx:attributes
<tx:method name=“accountMoney” propagation=“REQUIRED”/>
</tx:attributes>
</tx:advice>
aop:config
<aop:pointcut id=“pointcut” expression=“execution(* com.itholmes.service.UserService.*(…))”/>
<aop:advisor advice-ref=“txadvice” pointcut-ref=“pointcut”/>
</aop:config>
=========================================================================================
第一步:创建TxConfig类,通过使用注解让TxConfig类完全替代xml配置文件:
package com.itholmes.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
//@Configuration注解:表示该类是一个配置类
//@ComponentScan注解:相当于xml文件中的<context:component-scan base-package=“com.itholmes”/>。
//@EnableTransactionManagement注解:该注解的作用是开始事务
@Configuration
@ComponentScan(basePackages = “com.itholmes”)
@EnableTransactionManagement
public class TxConfig {
//创建数据库的连接池 与 xml配置文件中的内容是一一对应的
//@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。(和xml配置中的bean标签的作用是一样的)
@Bean
public DruidDataSource getDruidDataSource(){
DruidDataSource dataSource = new DruidDataSource();
//xml配置文件方式也是set注入方式,因此这里使用set也是对应配置文件中的。
dataSource.setDriverClassName(“com.mysql.cj.jdbc.Driver”);
dataSource.setUrl(“jdbc:mysql://localhost:3306/user_db?ServerTimezone=Aisa/shanghai”);
dataSource.setUsername(“root”);
dataSource.setPassword(“0818”);
return dataSource;
}
//创建JdbcTemplate对象
@Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource){
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
给大家送一个小福利
附高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、准备面试跳槽、自身职业规划迷茫的朋友们。
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource){
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-EtqUjcyq-1712075219825)]
[外链图片转存中…(img-IVDrarmx-1712075219826)]
[外链图片转存中…(img-POXujv8H-1712075219826)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
给大家送一个小福利
[外链图片转存中…(img-CT87ARfK-1712075219826)]
附高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、准备面试跳槽、自身职业规划迷茫的朋友们。
[外链图片转存中…(img-8cvZLIvu-1712075219827)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!