这个笔记不完整。
@Transactional 事物隔离级别
Atomic(原子性)
Consistency(一致性)
Isolation(隔离性)
Durability(持久性)
隔离级别
未提交读:允许一个事务读取另一个事物未提交的数据(可能引发脏读、不可重复读、幻读)
读写提交:一个事物只能读取另外一个事物已经提交的数据,不能读取未提交的数据(可能引发不可重复读、幻读)
可重复读:客服读写提交中的不可重复读现象(可能引发幻读)
串行化:要求所有的SQL按照顺序执行,保证了数据的一致性
使用隔离级别
1 2 3 4 @Transactional(isolation = Isolation.SERIALIZABLE) // 串行化 public int insertUser(){ // ... }
redis配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <!-- 不适用 lettuce 客户端 --> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <!-- 使用 jedis 客户端 --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
使用 jedis
客户端需要自定义Bean RedisConnectionFactory
为了查询 redis
显示字符串, 需要自定义Bean RedisTemplate
, 并设置字符串序列化方式
RedisTemplate操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Autowired private ReidsTemplate rt; // 地理位置操作接口 rt.opsForGeo(); // 散列操作接口 rt.opsForHash(); // 基数操作接口 rt.opsForHyperLogLog(); // 列表操作接口 rt.opsForList(); // 集合操作接口 rt.opsForSet(); // 字符串操作接口 rt.opsForValue(); // 有序集合操作接口 rt.opsForZSet(); // ## 绑定操作 - 用于连续处理 key 键对应值 rt.boundGeoOps("key"); // ... 其他方法不再赘述
Redis事物操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 redisTemplate.opsForValue().set("key1", "value1"); List list = (List)redisTemplate.execute((RedisOperations operations) -> { // 设置要监控key1 operations.watch("key1"); // 开启事务,在exec命令执行前,全部都只是进入队列 operations.multi(); operations.opsForValue().set("key2", "value2"); // operations.opsForValue().increment("key1", 1);// ① // 获取值将为null,因为redis只是把命令放入队列 Object value2 = operations.opsForValue().get("key2"); System.out.println("命令在队列,所以value为null【"+ value2 +"】"); operations.opsForValue().set("key3", "value3"); Object value3 = operations.opsForValue().get("key3"); System.out.println("命令在队列,所以value为null【"+ value3 +"】"); // 执行exec命令,将先判别key1是否在监控后被修改过,如果是则不执行事务,否则就执行事务 return operations.exec();// ② }); System.out.println(list);
Redis流水线
1 2 3 4 5 6 7 8 9 10 11 12 13 Long start = System.currentTimeMillis(); List list = (List)redisTemplate.executePipelined((RedisOperations operations) -> { for (int i=1; i<=100000; i++) { operations.opsForValue().set("pipeline_" + i, "value_" + i); String value = (String) operations.opsForValue().get("pipeline_" + i); if (i == 100000) { System.out.println("命令只是进入队列,所以值为空【" + value +"】"); } } return null; }); Long end = System.currentTimeMillis(); System.out.println("耗时:" + (end - start) + "毫秒。");
Redis发布订阅
实现 MessageListener
消息监听器
创建Bean RedisMessageListenerContainer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Autowired private ThreadPoolTaskScheduler taskScheduler; @Autowired private RedisConnectionFactory connectionFactory; @Bean public ThreadPoolTaskScheduler initTaskScheduler() { ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); taskScheduler.setPoolSize(20); return taskScheduler; } @Bean public RedisMessageListenerContainer initRedisContainer() { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); // Redis连接工厂 container.setConnectionFactory(connectionFactory); // 设置运行任务池 container.setTaskExecutor(taskScheduler); // 定义监听渠道,名称为topic1 Topic topic = new ChannelTopic("topic1"); // 使用监听器监听Redis的消息 // redisMsgListener 是自定义的消息监听器 container.addMessageListener(redisMsgListener, topic); return container; }
Redis使用Lua脚本
使用 DefaultRedisScript 创建脚本实例
使用 redisTemplate.execute 方法执行脚本实例
Redis 2.6 以后支持了 Lua
脚本执行具备原子性
Redis缓存
1 2 3 4 5 6 7 8 9 spring: cache: type: REDIS cache-names: test redis: cache-null-values: true # key-prefix: time-to-live: 0ms # use-key-prefix: true
相关注解: @EnableCaching
, @CachePut
, @Cacheable
, @CacheEvict
.
MongoDB配置
1 2 3 4 5 <!-- mongodb --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
1 2 3 4 5 6 7 8 spring: data: mongodb: database: test host: localhost port: 27017 password: 123456 username: 123456
使用 @Document
@Id
@Field
等定义POJO
MongoDB持久化接口
使用 MongoTemplate
进行
使用 MongoRepository
进行, 需要单独使用 @EnableMongoRepository
注解
基础方法不够用, 可以使用自定义查询注解 @Query
或者实现 <接口名>Impl
(这种命名时约定方式,可以通过注解EnableMongoRepository修改配置) 类即可
使用WebFlux可以改成 ReactiveMongoRepository
异步调用
相关注解 @EnableAsync
@Async
相关接口 AsyncConfigurer
异步消息AMQ
1 2 3 4 5 6 7 8 9 10 <!--依赖于starter,这样可以使用自动配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <!--依赖于连接池,这样就可以启用JMS连接池--> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> </dependency>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 spring: jms: pub-sub-domain: true # 是否使用发布订阅模式,默认为false,即用的是点对点的模式 template: default-destination: activemq.default.destination # 默认目的地址 activemq: packages: trust-all: true # 信任所有包 broker-url: tcp://localhost:61616 # ActiveMQ地址 user: admin # 用户名 password: admin # 密码 pool: enabled: true # 是否启用连接池 max-connections: 50 # 连接池最大连接数配置
通过 @JmsListener
进行配置监听消息
直接使用 JmsTemplate 发送消息
使用AMQP(RabbitMQ)
1 2 3 4 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
1 2 3 4 5 6 7 8 9 10 11 12 13 spring: rabbitmq: host: localhost # RabbitMQ 服务器地址 port: 5672 # RabbitMQ 端口 username: admin # RabbitMQ 用户 password: admin # RabbitMQ 密码 publisher-confirms: true # 是否确认发送的消息已经被消费 # 并非整体配置 # rabbitmq: # queue: # msg: spring-boot-queue-msg # RabbitMQ 的消息队列名称,由它发送字符串 # user: spring-boot-queue-user # RabbitMQ 的消息队列名称,由它发送用户对象
使用 RabbitTemplate
进行发送消息操作
使用 @RabbitListener
进行消息监听
定时任务
相关注解 @Scheduled
(可以配合 @Async
使用) @@EnableScheduling
WebSocket
1 2 3 4 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
需要自定义Bean ServerEndpointExporter
配置注解 @ServerEndpoint
@OnOpen
@OnClose
@OnMessage
@OnError
STOMP
为了解决 webSocket 的兼容性问题
使用注解 @EnableWebSocketMessageBroker
启动STOMP
使用接口配置 WebSocketMessageBrokerConfigurer
热部署
1 2 3 4 5 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
1 2 3 4 5 6 7 8 9 10 11 12 13 spring: devtools: lovereload: enabled: true # 是否启用一个livereload.com 兼容的服务器 port: 35729 # 端口livereload.com服务器端口 restart: enabled: true # 是否启用自动重启功能 additional-exclude: # 在原来的基础上新增不重启服务的文件夹目录 additional-paths: # 在原来的基础上新增重启服务的文件夹目录 exclude: META-INF/maven/**,META-INF/resources/**,resources/**,static/**,public/**,templates/**,**/*Test.class,**/*Tests.class,git.properties # 不重启服务的文件夹配置 poll-interval: 1000 # 设置对路径变化进行监测的时间间隔(以毫秒为单位) quiet-period: 400 # 在没有改变任何classpath的情况下,在重启被触发前的静默时长(以毫秒计) trigger-file: # 设置触发文件,当需要实际触发重启检查时,则需要修改这个文件
使用 shift+ctrl+alt+"/" (IDEA中的快捷键) 选择"Registry" 然后勾选 compiler.automake.allow.when.app.running