赞
踩
设置事务
@Transactional(isolation = Isolation.DEFAULT)
@Transactional(propagation = Propagation.REQUIRED)
开启事务
@EnableTransactionManagement
要开启 Spring 的事务管理,你需要在你的 Spring Boot 应用中添加 @EnableTransactionManagement
注解。通常这个注解会放在你的主应用类或者配置类上。
- @SpringBootApplication
- @EnableTransactionManagement
- public class Springboot01CenterTxApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(Springboot01CenterTxApplication.class, args);
- }
-
- }
@Transactional
注解可以加在服务类的方法上,表示该方法是一个事务。这个注解可以接收多个参数来控制事务的行为,比如 isolation
和 propagation
。- @Transactional
- @Service
- public class CustomerServiceImp implements ICustomerService{
-
-
- @Resource
- private ConsumeMapper mapper;
-
- @Override
- public void batchAdd() {
- mapper.insert(new Customer(1,"台湾君越酒店","五星级","佩洛西1","12345678"));
- int a = 10/0;
- mapper.insert(new Customer(2,"台湾君越酒店","五星级","佩洛西1","12345678"));
- mapper.insert(new Customer(3,"台湾君越酒店","五星级","佩洛西1","12345678"));
-
- }
- }

Isolation:定义多个事务之间的隔离级别,主要有以下几个选择:
Isolation.DEFAULT
:使用数据库默认的隔离级别。
Isolation.READ_UNCOMMITTED
:允许读取未提交的数据。
Isolation.READ_COMMITTED
:确保只读取已提交的数据。
Isolation.REPEATABLE_READ
:确保在同一事务中多次读取的数据一致。
Isolation.SERIALIZABLE
:完全隔离的事务,确保每个事务都按照某个顺序执行(性能较低)。Propagation:定义事务的传播行为,主要有以下几种:
Propagation.REQUIRED
:如果当前存在事务,则加入该事务;如果没有事务,则创建新的事务。
Propagation.REQUIRES_NEW
:创建一个新的事务,如果当前存在事务,则将当前事务挂起。
Propagation.NESTED
:如果当前存在事务,则在嵌套事务中执行;否则,就执行与REQUIRED
相同的方式。
Propagation.SUPPORTS
:如果当前存在事务,则加入该事务;否则以非事务方式执行。
Propagation.NOT_SUPPORTED
:以非事务方式执行,挂起当前事务(如果存在)。
Propagation.NEVER
: 不支持事务,如果当前存在事务则会抛出异常。
你可以创建测试用例,验证事务的正确性。例如,如果在一个事务中执行了多个数据库操作,而其中一个操作失败,则整个事务应回滚,数据库应保持在失败前的状态。
- public void batchAdd() {
- mapper.insert(new Customer(1,"台湾君越酒店","五星级","佩洛西1","12345678"));
- // int a = 10/0;
- mapper.insert(new Customer(2,"台湾君越酒店","五星级","佩洛西1","12345678"));
- mapper.insert(new Customer(3,"台湾君越酒店","五星级","佩洛西1","12345678"));
-
- }
- public void batchAdd() {
- mapper.insert(new Customer(1,"台湾君越酒店","五星级","佩洛西1","12345678"));
- int a = 10/0;
- mapper.insert(new Customer(2,"台湾君越酒店","五星级","佩洛西1","12345678"));
- mapper.insert(new Customer(3,"台湾君越酒店","五星级","佩洛西1","12345678"));
-
- }
在项目开发中,绝大多数情况下都是通过同步方式处理业务逻辑的,但是比如批量处理数据,批量发送 邮件,批量发送短信等操作 容易造成阻塞的情况,之前大部分都是使用多线程来完成此类任务而在 Spring 3+之后,就已经内置了@Async注解来完美解决这个问题,从而提高效率。
使用的注解
@EnableAsync 启动类上开启基于注解的异步任务
@Async 标识的方法会异步执行
在你的主应用类或配置类上添加 @EnableAsync
注解。这样 Spring 就会扫描带有 @Async
注解的方法并在异步执行它们。
- @SpringBootApplication
- @EnableAsync
- public class Springboot02CenterAysncApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(Springboot02CenterAysncApplication.class, args);
- }
-
- }
在你的服务类中,可以通过 @Async
注解来标记要异步执行的方法。这个方法应该返回 void
或者是 Future
、CompletableFuture
等可用于异步结果的类型。
- @Service
- public class CustomerServiceImp implements ICustomerService{
-
- @Override
- @Async
- public void batchAdd() {
-
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("======>批量新增");
- }
- }
在其他服务或控制器中,可以调用上述异步方法。注意,由于这些方法是异步执行的,所以调用这些方法后不会等待其完成,调用者会立即继续执行后面的代码。
- @RestController
- public class CustomrControllerImp {
-
- @Autowired
- private ICustomerService service;
-
- @RequestMapping("/add")
- public String batchAdd() {
- service.batchAdd();
- return "成功";
- }
-
- }
总结
通过
@EnableAsync
和@Async
注解,Spring 允许你轻松地将方法异步执行,从而提高应用的吞吐量和响应速度。同时,自定义配置线程池也可以使你更好地控制异步任务的执行。使用异步任务时要注意,异步方法不能被同一类中的其他方法直接调用,因为那样不会触发代理,方法会在同一线程中执行。
SpringTask
在项目开发中,经常需要执行一些定时任务,比如 每月1号凌晨需要汇总上个月的数据分析报表; 每天 凌晨分析前一天的日志信息等定时操作。Spring 为我们提供了异步执行定时任务调度的方式
使用的注解
@EnableScheduling启动类上开启基于注解的定时任务
@Scheduled标识的方法会进行定时处理
需要通过 cron 属性来指定 cron 表达式:秒 分 时 日 月 星期 年
在线生成cron表达式 http://cron.qqe2.com/
在你的主应用类或配置类上添加 @EnableScheduling
注解,以启用 Spring 的定时任务功能。
- @SpringBootApplication
- @EnableScheduling
- public class Springboot03CenterJobApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(Springboot03CenterJobApplication.class, args);
- }
-
- }
在你的服务类中,可以使用 @Scheduled
注解来标识需要定时执行的方法。可以通过 cron
属性来指定 cron 表达式。
- @Service
- public class MyScheduledService {
-
- // 每分钟执行一次
- @Scheduled(cron = "0 * * * * ?")
- public void executeTaskEveryMinute() {
- System.out.println("Executing task every minute: " + System.currentTimeMillis());
- }
-
- // 每天凌晨 1 点执行
- @Scheduled(cron = "0 0 1 * * ?")
- public void executeTaskAtOneAM() {
- System.out.println("Executing task at 1 AM: " + System.currentTimeMillis());
- }
-
- // 每周一执行
- @Scheduled(cron = "0 0 12 ? * MON")
- public void executeTaskEveryMonday() {
- System.out.println("Executing task every Monday at noon: " + System.currentTimeMillis());
- }
- }

cron 表达式的格式如下:
秒 分 时 日 月 星期 年(可选)
- 秒:0-59
- 分:0-59
- 时:0-23
- 日:1-31
- 月:1-12 或者 JAN-DEC
- 星期:1-7(1=星期日)或 SUN-SAT
- 年:1970-2099(可选)
示例 cron 表达式
"0 * * * * ?"
:每分钟执行一次"0 0 1 * * ?"
:每天凌晨 1 点执行"0 0 12 ? * MON"
:每周一中午 12 点执行"0 0/5 * * * ?"
:每 5 分钟执行一次你可以使用在线工具生成和测试 cron 表达式,例如 在线Cron表达式生成器。
总结
通过
@EnableScheduling
和@Scheduled
注解,Spring 提供了一种简单而强大的方式来实现定时任务。你可以根据需要自定义 cron 表达式,以满足不同的调度需求。
第一步添加坐标
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-mail</artifactId>
- </dependency>
第二步开启配置
配置邮箱信息
spring.mail.username=
spring.mail.password=
发送邮件服务器
spring.mail.host=smtp.qq.com
- spring.mail.username=3058389349
- spring.mail.password=topqjgemcudxdfch
- spring.mail.host=smtp.qq.com
- spring.mail.properties.smtp.ssl.enable=true
第三步编写代码
邮件收发核心类
JavaMailSenderImpl javaMailSender;
封装简单的邮件内容
SimpleMailMessage
封装复杂的邮件(携带附件)
MimeMessage MimeMessageHelper
- @SpringBootTest
- class Springboot04CenterMailApplicationTests {
-
- @Autowired(required = false)
- private JavaMailSenderImpl javaMailSender;
-
- //发送简单邮件
-
- @Test
- void show1() {
- //1.创建邮件对象
- SimpleMailMessage simpleMailMessage=new SimpleMailMessage();
- //2.设置信息
- simpleMailMessage.setSubject("疫情全面放开");
- simpleMailMessage.setText("2022年好难,做了11个月的核酸,结果在第12个月阳了~~~");
- simpleMailMessage.setFrom("3058389349@qq.com");
- simpleMailMessage.setTo("3418813089@qq.com");
-
- //3.发送邮件
- javaMailSender.send(simpleMailMessage);
- System.out.println("发送成功!!!");
-
- }
-
- //发送复杂邮件
- @Test
- void show2() throws MessagingException {
- //1.创建邮件对象
- MimeMessage mimeMessage = javaMailSender.createMimeMessage();
- //2.创建MimeMessageHelper
- MimeMessageHelper mimeMessageHelper=new MimeMessageHelper(mimeMessage,true);
- //3.设置信息
- mimeMessageHelper.setSubject("程序员的误解");
- mimeMessageHelper.setText("程序员是个<span style='color:red'>高薪,高危</span>的职业",true);
- mimeMessageHelper.addAttachment("pp.jpg",new File("D:\\1\\图片\\pp.jpg"));
- mimeMessageHelper.setFrom("3058389349@qq.com");
- mimeMessageHelper.setTo("3418813089@qq.com");
- //4.发送邮件
- javaMailSender.send(mimeMessage);
-
-
- }
-
- @Test
- public void show(){
- //1、new Jedis对象即可
- Jedis jedis=new Jedis("127.0.0.1",6379);
- //jedis所有的命令
- System.out.println(jedis.ping());
- }
-
- }

- <!-- redis依赖 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
- <dependency>
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter</artifactId>
- <version>RELEASE</version>
- <scope>test</scope>
- </dependency>
- spring.redis.host=localhost
- spring.redis.port=6379
- //演示1(专用对象)
- @Autowired
- public RedisTemplate redisTemplate;
-
- //演示2(专用字符串key value均是String)
- @Autowired
- public StringRedisTemplate stringRedisTemplate;
-
- //演示3(自定义)
- @Autowired
- public RedisTemplate jsonRedisTemplate;
- @Autowired
- public StringRedisTemplate stringRedisTemplate;
- @Test
- public void stringRedisTemplate(){
- //1.key相关
- Set<String> keys = stringRedisTemplate.keys("*");
- for (String key : keys) {
- System.out.println(key);
- }
- //2.各种类型支持
- stringRedisTemplate.opsForValue();
- stringRedisTemplate.opsForList();//List
- stringRedisTemplate.opsForHash();//hash
- stringRedisTemplate.opsForSet();//set
- stringRedisTemplate.opsForZSet();//zset
- //3.举例字符串
- stringRedisTemplate.opsForValue().set("name","水果");
- String name = stringRedisTemplate.opsForValue().get("name");
- System.out.println(name);
- //4.操作list列表
- stringRedisTemplate.opsForList().leftPush("myList","香蕉");
- stringRedisTemplate.opsForList().leftPush("myList","苹果");
- stringRedisTemplate.opsForList().leftPushAll("mylistAll","苹果","香蕉","香蕉");
- List<String> list = stringRedisTemplate.opsForList().range("mylistAll",0,2);
- System.out.println(list);
- }

注意:
1.测试RedisTemplate与stringRedisTemplate存的数据相互独立
2.redisTemplate默认使用key序列化方式和value的序列化方式都使用的是jdk serializer序列化
所以存对象会乱码
- @Autowired
- public RedisTemplate redisTemplate;
- @Test
- public void show2(){
-
- ValueOperations valueOperations = redisTemplate.opsForValue();
- valueOperations.set("name","蜜蜂");
- String name = (String) valueOperations.get("name");
- System.out.println(name);
-
-
- redisTemplate.opsForValue();//String
- redisTemplate.opsForList();//List
- redisTemplate.opsForHash();//hash
- redisTemplate.opsForSet();//set
- redisTemplate.opsForZSet();//zset
-
-
- Student stu1 = new Student(1,"蜜蜂","采蜜");
- redisTemplate.opsForValue().set("stu1",stu1);
- Student ss1 = (Student)redisTemplate.opsForValue().get("stu1");
- System.out.println(ss1);
-
- redisTemplate.opsForList().leftPushAll("mylist","睡觉","游戏");
- List<String> list = redisTemplate.opsForList().range("mylist",0,-1);
- for (int i = 0; i < list.size(); i++) {
- String s = list.get(i);
- System.out.println(s);
- }
-
- System.out.println("打印默认序列策略"+redisTemplate.getDefaultSerializer());
-
-
- }

JsonRedisTemplate
是 Spring Data Redis 提供的一个模板类,专门用于操作 Redis 数据库并以 JSON 格式序列化和反序列化对象。
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
然后,你可以创建一个 JsonRedisTemplate
的 Bean。通常,我们会通过 @Configuration
类来配置。
- package com.xn.springboot_redis01.config;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
- import org.springframework.data.redis.serializer.StringRedisSerializer;
-
- import java.net.UnknownHostException;
-
-
- @Configuration
- public class RedisConfig {
-
-
- @Bean
- public RedisTemplate<Object, Object> jsonRedisTemplate(
- RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
- //1.创建自定义模板类
- RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
- //配置json类型的序列化工具
- template.setKeySerializer(new StringRedisSerializer());//这样key会用字符串方式保存
- template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
-
- template.setConnectionFactory(redisConnectionFactory);
-
- return template;
- }
-
-
-
- }

- @Autowired
- public RedisTemplate jsonRedisTemplate;
- @Test
- public void show3(){
- //保存对象
- Student stu = new Student(1,"彭老师","拉面");
- jsonRedisTemplate.opsForValue().set("stu",stu);
- //获取对象
- Object s1 = jsonRedisTemplate.opsForValue().get("stu");
- String jsonS1 = JSONObject.toJSONString(s1);
- Student s11 = JSONObject.parseObject(jsonS1,Student.class);
- System.out.println(s11);
-
- Student stu2 = new Student(2,"彭老师","拉面");
- Student stu1 = new Student(2,"彭老师","拉面");
- Student stu3 = new Student(2,"彭老师","拉面");
- List<Student> students = Arrays.asList(stu1, stu2, stu3);
- jsonRedisTemplate.opsForValue().set("stus",students);
- //必须Object接受,利用ObjectMapper对象转换,如果强制转换会报错
- Object data = jsonRedisTemplate.opsForValue().get("stus");
- String dataJson = JSONObject.toJSONString(data);
- //将JSON类型转为List
- List<Student> stus = JSONObject.parseArray(dataJson, Student.class);
- System.out.println(stus);
-
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。