- 博客(35)
- 问答 (2)
- 收藏
- 关注
原创 预留库存的实现
这里使用悲观锁的思想,利用mysql数据库在update,insert,delete时对应数据加上行锁的特性解决并发冲突,保证了在更新数据时,数据是最新的,且其它update,insert,delete操作被阻塞,乐观锁与悲观锁的具体参考文章“乐观锁与悲观锁的使用场景”。
2025-04-29 21:16:30
213
原创 乐观锁与悲观锁的使用场景
高写入比例的数据库操作:如果系统中有很多写操作,并且这些写操作可能会频繁地相互干扰,那么使用悲观锁可以有效避免数据不一致的问题。读操作远多于写操作的场景:例如在线阅读平台、新闻网站等,这类应用主要以读取信息为主,很少会有数据修改的需求,采用乐观锁可以减少锁带来的性能损耗。低冲突概率的环境:当系统预期不同事务之间很少会对同一数据进行修改时,使用乐观锁可以获得更好的性能表现。比如库存管理系统中,对于非热销商品的库存调整。选择哪种锁机制应基于具体的应用场景以及系统对性能和一致性的需求来决定。
2025-04-09 22:01:29
1121
原创 消息重试处理达到最大时,死信队列与异常队列的异同
spring:rabbitmq:listener:simple:acknowledge-mode: auto # 自动ackretry:enabled: true # 开启消费者失败重试initial-interval: 1000ms # 初识的失败等待时长为1秒multiplier: 1 # 失败的等待时长倍数,下次等待时长 = multiplier * last-intervalmax-attempts: 3 # 最大重试次数。
2024-12-10 18:17:30
359
原创 seata 各个微服务回滚的时机
在Seata中,当你在服务方法上使用@GlobalTransactional注解时,Seata会为该全局事务创建一个事务上下文,并在远程服务调用时传递这个事务上下文。:当你通过OpenFeign发起远程调用时,Seata会拦截这个调用,并将当前的全局事务XID(事务ID)通过HTTP请求头传递给远程服务。:在远程服务端,Seata的拦截器会检查请求头中的XID,并将其绑定到当前的服务线程上下文中,使得远程服务也参与到同一个全局事务中。TC根据全局事务的状态,可能会触发全局事务的回滚。
2024-11-25 14:41:46
730
原创 openfeign微服务应用中,触发降级逻辑的情况。
在启用了断路器(Circuit Breaker)的情况下,如果ItemClient服务的错误率超过了阈值,断路器会打开,后续的调用会直接执行降级逻辑,而不会尝试远程调用。:如果ItemClient服务在处理请求时抛出了异常(未被catch的异常)(例如,数据库访问异常、业务逻辑异常等),那么调用也会失败,并且会触发降级。:如果ItemClient服务本身不可用,比如服务宕机或停止,那么调用将会失败,并且会执行ItemClientFallback中的逻辑。
2024-11-24 15:43:03
263
原创 spring中的动态代理
这个例子中,我们将创建一个简单的Hello接口,一个实现了这个接口的类HelloImpl,以及一个代理类HelloProxyHandler,它将作为我们的代理处理器。在这个例子中,我们将创建一个简单的Hello类,一个实现了Hello接口的HelloImpl类,以及一个代理类HelloProxy,它将作为我们的代理处理器。JDK动态代理是基于Java反射机制实现的,只能为实现了接口的类创建代理。特点:可以代理没有实现接口的类,但无法代理final类和方法。限制:被代理的类必须实现至少一个接口。
2024-07-22 22:35:34
356
原创 AQS的理解
表示锁的状态:在独占锁(如ReentrantLock)的实现中,同步状态通常表示锁的持有情况。例如,状态为0可能表示锁当前是可用的,而状态为1或更大值可能表示锁已被占用,并且如果锁是可重入的,状态值可能会表示锁被同一个线程获取的次数。资源可用性:在信号量(如Semaphore)中,同步状态表示可用的许可数量。当线程尝试获取许可时,它需要更新状态以减少可用的许可数;当线程释放许可时,它需要更新状态以增加可用的许可数。
2024-07-22 21:28:40
938
原创 Mysql数据库事务与锁的理解
一个事务是一组SQL语句的集合,这些语句要么全部成功,要么全部失败。事务确保了数据库操作的原子性、一致性、隔离性和持久性(ACID特性)。
2024-07-19 23:41:09
350
原创 数据库发生死锁常见的场景
例如,事务A先锁定资源X,再锁定资源Y;如果另一个事务需要内部事务锁定的资源,但又被另一个需要外部事务资源的事务阻塞,就可能形成死锁。如果事务执行时间过长,它可能会锁定某些资源较长时间,导致其他等待这些资源的事务被阻塞。多个事务同时尝试更新同一记录,其中一个事务可能先锁定记录,随后其他事务试图锁定同一记录,导致等待和潜在的死锁。如果表中缺乏适当的索引,事务可能需要执行全表扫描,这可能导致表级锁,增加死锁的可能性。当事务间形成一个循环等待链,每个事务都在等待另一个事务释放锁时,就会发生死锁。
2024-07-19 23:31:39
437
原创 生产者与消费者的几种解决方式
以上每种方式都有其适用场景,选择哪一种取决于具体的需求和设计考量。例如,BlockingQueue提供了更简洁的API,并且能够处理多种不同的并发场景,而使用wait()这是最基础的方式,通过synchronized关键字锁定资源,并使用对象的wait()和notify()方法来控制线程的等待与通知。Java中的java.util.concurrent包提供了BlockingQueue接口,它简化了生产者与消费者的实现。信号量(Semaphore)可以用来控制对资源的访问。
2024-07-17 11:19:44
180
原创 springboot中跨域问题的几种解决方式
为了全局启用跨域,可以创建一个配置类,实现WebMvcConfigurer接口,并覆盖其addCorsMappings方法。如果你想让一个控制器类下的所有方法都支持跨域,可以在类级别使用@CrossOrigin注解。对于特定的接口,可以在控制器方法上使用@CrossOrigin注解来开启跨域支持。还可以通过注册一个CorsFilter Bean来实现全局跨域配置。
2024-06-03 19:41:09
490
原创 springboot数据校验的相关异常
例如,当一个表单提交到Controller时,如果表单中的某个字段不符合校验规则(如@NotNull、@Size等),则会抛出此异常。例如,当使用@RequestBody注解处理JSON请求体时,如果JSON格式不正确或无法映射到目标对象,则会抛出此异常。例如,如果Controller方法期望接收一个整数参数,但实际请求中传递的是字符串,且无法转换为整数,则会抛出此异常。例如,如果JSON请求体的格式不正确,无法解析为预期的对象,则会抛出此异常。例如,当用户访问了一个不存在的URL时,会抛出此异常。
2024-05-06 18:31:57
467
原创 拦截器放行静态资源
为了避免这个异常,您可以在拦截器中添加一个条件来检查处理程序对象的类型,以确保只有当处理程序对象是 HandlerMethod 类型时才进行转换。这样就可以避免在处理静态资源请求时出现类型转换异常。通过添加对处理程序对象类型的检查,我们确保只有当处理程序对象是 HandlerMethod 类型时才尝试转换,并且在其他情况下直接放行请求,避免了类型转换异常。静态资源请求的处理程序对象是 ResourceHttpRequestHandler,而不是 HandlerMethod。
2024-05-03 23:29:30
361
原创 js吸顶与浮动广告的实现
浮动广告是,它对大容器进行相对定位,设置定时器,改变它的left ,top值,注意的是大容器的宽高为100vw 100vh,鼠标滚动时,大容器的left=window.scrollX top =window.scrollY,这样我们缩放界面或者是滚动界面都能在当前视口看见广告移动。吸顶我这里没有用fixed,用的使absolute,主要思想使当鼠标滚动距离大于top时,top = window.scrollY ,小于时,恢复原来的top值。
2023-12-22 13:39:34
817
原创 IO流的学习与使用
什么是IO流I:是从外部设备到应用程序之间的数据传递,常见的外部设备包括文件、管道、网络连接O:是从应用程序到外部设备的数据传递分类按流向分为,输入流,输出流按处理数据单位:字节流、字符流字节流的应用public class TestStream { public static void main(String[] args) throws IOException { File file = new File("E:\\MultiMediaOpt\\Test\\Te
2022-05-29 18:23:23
111
原创 迭代器的学习与使用
什么是迭代器Iterator提供了同一遍历操作集合元素的统一接口,Collection接口实现了Iterable接口,每个集合都通过实现Iterable接口中的iterator()方法返回Iterator接口的实例,然后对集合的元素进行迭代操作,请看如下代码:package Test.Test09;import java.util.*;public class TestIterator { public static void main(String args[]){ Lis
2022-05-22 16:29:13
175
原创 自动装箱与拆箱
什么是自动装箱与拆箱自动装箱时把基础数据类型转为对应的封装类,拆箱是将封装类自动转为对应的基本数据 请看如下代码:package Test.Test05;import java.lang.*;public class Test05 { public static void main(String args []){ Integer a = 10; int b = a+100; System.out.pr
2022-05-14 16:21:18
132
原创 泛型的学习
泛型应用到类上package Test.Test01;import java.util.Scanner;public class Test01 { public static void main(String args[]){ Person<String> person = new Person<>("yang","money"); System.out.println(person); Dog www = new Do
2022-05-07 16:19:01
83
原创 抽象类与抽象方法
抽象类是用abstract关键字修饰的类,抽象方法是用abstract关键字修饰的方法我们需要注意的是抽象类不能够实例化(既不能够new对象),抽象类的存在是为了继承,是为了形成多态机制,请看如下代码:package Test.Test06;public class Test06 { public static void main(String args[]){ Animal human = new Person(); Animal chicken = new Chick
2022-05-01 18:29:33
90
原创 内部类的用法
被static修饰的内部类package Test.Test03;public class Test03 { public static void main(String args[]){ Human.Dog dog = new Human.Dog("大黄",10); System.out.println(dog); dog.print(); Human.Dog dog2 = new Human.Dog("大黑",11);
2022-04-24 16:03:32
219
原创 读ArrayList有感
ArrayListArrayList是什么?简单来说是一个处理变长数组的列表,这个类的成员变量是一个Object类,和一个表示数组元素个数的size,如下图它有三个构造方法,这里只介绍一个常见的,源代码如下: public ArrayList(int initialCapacity) {//初始容量(长度) if (initialCapacity > 0) { this.elementData = new Object[initialCapacit
2022-04-20 21:12:16
388
原创 方法重载的用法
方法重载方法重载的好处是什么,我们为什么要用方法重载当我们要实现两个数的加法,通常是使用如下代码:public class Test{ public static int sum(int a,int b){ return a+b; } public static double sum1(double a,double b){ return a+b; }public static double sum2(double a,double b,double c){ return
2022-04-17 23:31:23
741
原创 Java多态用法
何为多态:多态既一个方法有两种形态,请看如下代码静态绑定:在编译时,指向子类的父类对象绑定父类的方法; class Animal{ String name; int age; Animal(){} void eat(){ System.out.println("动物吃食物"); } void print(){ } }public class Dog extends Animal{ String hair; Dog(Strin
2022-04-10 22:40:49
232
原创 fianl用法
关键字final的学习final修饰成员变量,局部变量,表示修饰的值不变,请看下列代码final修饰成员变量class Cat{final String name="huang";final int age = 14;Cat(String name,int age){ this.name = name;this.age = age;}}public class Test{public static void main(String args[]){ Cat cat = new C
2022-04-02 16:25:40
122
原创 一个关于自己的类及学生台控制系统
一个关于自己的一个类public class MyselfObject { String name; int age; private double height; private double myMoney;//声明各属性 private double weight; private String [][] timeTable ; MyselfObject(String name,int age,double myMoney,
2022-03-28 00:01:59
350
原创 super用法
关键字super在继承中的用法1 super()调用父类的构造方法public class Super extends Father{ public static void main(String args[]){ Super s = new Super(); Super ss = new Super(2); } public Super(){ super(10); System.out.println("调用子类构
2022-03-19 23:55:38
1035
原创 冒泡排序法
冒泡排序法import java.util.Scanner;import java.util.Arrays;public class MaoPao{public static void main(String args[]){ int a[] = new int[10]; System.out.println("请输入10个数:"); input(a); System.out.println("排序后:"); paixv(a); System.out.println(Arrays.toS
2022-03-17 16:13:42
130
原创 Java第二篇Blog
选择排序法import java.util.Arrays;//导入包import java.util.Scanner;public class XuanZhe{public static void main(String args[]){ Scanner in = new Scanner(System.in); A yang = new A(); int a [] = new int[10]; input(a);//调用方法输入数据 yang.paixv(a);//调用方法排序
2022-03-13 22:21:20
108
原创 Java第一篇Blog
直接排序法import java.util.Scanner;import java.util.Arrays;public class ZhiJie{ public static void main(String[] args) { Scanner in = new Scanner(System.in);//创建Scanner对象 int n = in.nextInt();//得到一个整型数据 int [] a = new int[n];/
2022-03-06 12:14:35
329
空空如也
编译通过,但是程序运行到b.paixv(a)就停止了。
2022-03-10
编译通过,运行出错。输入有问题
2022-03-09
TA创建的收藏夹 TA关注的收藏夹
TA关注的人