Spring事务失效场景

工作中经常会使用事务,事务保证了操作的一致性,要嘛全部成功,有一个失败则全部失败。类似于与操作。其中事务具备ACID四个特性,包含原子性,一致性,隔离性,持久性。Spring开发了spring-tx模块封装了事务,包含有编程式事务与声明式事务。其中编程式事务使用TransactionTemplate实现,声明式事务使用Transactional注解。但是事务有时候会失效导致脏数据的产生,下面来进行实践测试。

阅读更多

使用Redis作为Mybatis二级缓存

本文主要记录redis作为mybatis二级缓存时所遇到的问题,因为mybatis以及缓存基于sqlsession,会话完成后,缓存数据就会被清空,二级缓存基于mapper,虽然解决了sqlsession的问题,但是还是基于本地内存,应用被杀掉后,缓存还是被清空,并且分布式环境下会出现缓存一致性问题。所以现在大部分二级缓存都是使用redis实现,有效解决分布式情况下缓存问题。当然,redis分布式缓存也会存在一定的问题。后面有时间再记录。

阅读更多

Jackson枚举序列化与反序列化

本文主要记载Jackson按需求序列化枚举以及反序列化枚举的实现,踩过一些坑,所以做下笔记。Java默认序列化枚举的Name字段,比如ENUM_SEX_MAN(0),默认只会序列化ENUM_SEX_MAN。不满足实际需求。所以项目中需要做一些自定义。

阅读更多

SpringCloud网关下Springdoc聚合API配置

之前使用SpringBoot一般会使用SpringFox Swagger进行API接口管理,但是如果基于Spring Cloud开发,SpringFox 库最重要的问题是缺乏对WebFlux 构建的反应式 API的支持,并且也没有API聚合功能。通过搜索,我们发现了SpringDoc,支持WebMvc支持,WebFlux支持,Javadoc 支持等,支持非常广,可以参考SpringDoc官网。下面就来测试下

阅读更多

Seata初探

项目中需要使用到分布式事务,这里我们选择Seata进行开发。因为Seata支持ORM方式较多,这是官网的说明,Seata 虽然是保证数据一致性的组件,但对于 ORM 框架并没有特殊的要求,像主流的Mybatis,Mybatis-Plus,Spring Data JPA, Hibernate等都支持。这是因为ORM框架位于JDBC结构的上层,而 Seata 的 AT,XA 事务模式是对 JDBC 标准接口操作的拦截和增强。,实现方式页比较多,比如AT模式,TCC模式,Saga模式,XA模式。 本篇文章主要记录Seata的搭建过程以及Seata在Spring Cloud下的使用。

阅读更多

关于Gitlab自动化CI使用记录

公司使用Gitlab进行代码管理,CI工具可以使用Gitlab Runner,Jenkins等,这里选用Gitlab Runner。这样我们就不必每个项目都写脚本进行配置,比较烦Jenkins的一堆配置,并且Runner可以无障碍迁移。这里记录下整个使用过程及其中遇到的问题及优化。

阅读更多

Spring实现接口加密解密

本篇文章同样使用AOP注解代理,实现运行时的接口加密解密。项目开发中有一些接口数据是敏感数据,比如用户手机号,真是姓名,身份证,密码等等。但是有一些接口是不用加密的,所以我们需要一种方式,实现与业务脱离,可自定义使用场景的代理方式。

阅读更多

Spring实现注解鉴权

项目开发中经常会对用户请求进行鉴权,用户是否有调用当前接口的权限等。单体应用我们通常会使用WebSecurityConfigurerAdapter来认证用户请求,并通过Spring注解PreAuthorize等进行鉴权,如果是微服务应用,有两种方式可以实现鉴权,第一种是将所有角色和权限从数据库中查询出来缓存到redis,然后通过网关去鉴权。第二种我们可以在网关中只判断token是否合法,如果合法就将用户信息下发到子服务中自主鉴权。本篇文章使用第二种方式,通过Spring AOP注解的方式实现自动鉴权操作,本篇文章主要做一个记载,并不是关于Spring AOP的详细使用文章。

阅读更多

MySQL全文索引

项目开发中,有很多类似模糊查询的需求,比如模糊查询某个公司的名称,用户名等等。一般来说开发中都会使用like进行模糊查询。并且针对like模糊的字段加上索引,使得like可以走索引加速查询。但是like+索引的模式只能在后模糊下有效,像这样xxx%,全模糊%xxx%和前模糊%xxx会导致索引失效,这样查询就比较慢了。关于索引失效的问题,前模糊我们可以使用翻转函数reverse让索引有效并加速查询,但是全模糊还是会让索引失效。针对全模糊的场景,我们可以使用之前的ElasticSearch搜索引擎技术,也可以使用MySQL全文索引。

阅读更多

Spring源码结构

现在做后台开发全是Spring的一堆框架,无论是使用的Spring MVC,SpringBoot,Spring Cloud都是基于Spring作为基础进行搭建的。从本篇文章开始将开始深入研究Spring的实现方式,架构,核心的原理等等。

阅读更多

Java使用JNI调用动态链接库

项目中有个需求,需要根据用户上传的图片分析出用户的一些面部特征,血压,血氧等用户体征数据,Java层接收用户上传图片,保存,然后将图片地址传递给C++算法去处理,算法层计算出结果并返回给Java层一个对象。这里做个简单的demo模拟这个需求,大概需要的技术有C++,JNI Java等。

阅读更多

BIO简单使用

从本章开始,后面一段时间都学习网络和IO方面的知识。网络和IO都是知识盲区,慢慢整理,争取把这部分梳理清楚,首先IO是Input和Output的简写。代表输入和输出。而从位置来区分,又分为本地IO和网络IO。本地IO代表本机系统内的设备进行通信,网络代表本机系统和网络上的系统进行通信。而网络通讯模型又分为BIO(同步阻塞IO),NIO(同步非阻塞IO),AIO(异步非阻塞IO)。本章主要记录BIO的简单使用。

阅读更多

AQS分层及自定义锁

之前写了一些锁使用文章,比如ReentrantLock(独占锁),ReentrantReadWriteLock(读写锁)等,也写了一些线程通讯类Condition(条件队列),CountDownLatch(倒计时器),CyclicBarrier(循环栅栏),Semaphore(信号量)等,底层都是使用AQS实现的。本篇文章主要记录AQS内部变量方法的使用及作用,还使用AQS实现了自定义锁的实现。比较简单,如需编写复杂的自定义锁也可以参考ReentrantLock(独占锁),ReentrantReadWriteLock(读写锁)。

阅读更多

Condition原理解析

在之前介绍ReentrantLock锁使用文章中,简单的介绍了Condition在ReentrantLock中的使用,Condition主要用作线程之间的通信,等待,唤醒等功能,但是Condition是如何实现线程之间的通信的呢?本篇文章会罗列出所有Condition的API,然后介绍每个APi的功能并且描述Condition底层的实现原理。

阅读更多

ReentrantReadWriteLock原理解析

前面在介绍ReentrantLock提到过SHARED锁和EXCLUSIVE锁,我们使用ReentrantLock的时候,虽然因为自旋效率较高,但有些情况下我们不必要使用独占锁,比如读写场景,读较多,写较少,可以让多个线程同时取读,当有线程写的时候让其余的读写线程等待即可。这样提高了读的效率。ReentrantReadWriteLock从名字来看就是读写锁,读读共享,读写互斥。

阅读更多

Docker调整时区

使用Docker搭建redmine容器时忘记更改时区,导致运行起来后容器的时区还是utc时区,生产环境需要多考虑周边的配置。本篇文章主要记录Docke从编译,运行和运行时容器的时区配置,以供后续直接使用。

阅读更多

CyclicBarrier使用

上一篇文章使用CountDownLatch模拟一家人出行旅行的计数器模型,也可以使用CyclicBarrier实现,CyclicBarrier翻译成英文为循环栅栏,CyclicBarrier的内部原理与CountDownLatch基本一样。不同地方在于CountDownLatch使用Node管理线程中断,而CyclicBarrier使用Condition队列。其实内部都一样。文章记录CyclicBarrier的使用过程以及其内部实现原理,供后续使用,复习,复盘等。

阅读更多

Semaphore使用

Semaphore是一个计数信号量,常用于限制可以访问某些资源(物理或逻辑的)线程数目。比如我们的接口只能同时有1000个连接访问,比如停车场只能停50辆车等等,Semaphore内部通过AQS实现公平锁和非公平锁。

阅读更多

CountDownLatch使用

项目开发中有一些需求,比如需要一些线程执行完成后再去执行一些操作。此时就需要用到CountDownLatch这个类,CountDownLatch是一个计数器,每当执行一个任务完成时调用计数器减一,直到count=0时才会执行后续的线程。CountDownLatch中的count不可重置。如果需要对count进行重置,官方建议使用CyclicBarrier,在后面的文章中会进行使用介绍。

阅读更多

ReentrantLock使用

之前有篇文章分析了Synchronized如何锁以及锁升级的过程,我们可以使用Synchronized来保证线程安全,为什么Java还设计一个AQS的东西来保证线程安全呢?我也不是特别清楚,一边读源码,一边梳理。本文主要记录ReentrantLock的使用及部分源码的梳理过程。

阅读更多