기반 SpringBoot 2.X의
같은 레디 스 자주 관계형 데이터베이스의 개발에 사용 문제, 사실, 비 관계형 데이터베이스, 또한 거래에 대한 지원을하고, 사용에 거래 SpringBoot을 레디 스 방법 용지에 대해 설명합니다.
관련 프리젠 테이션을 참조 할 수 있습니다 사항 :
0 귀착
사고 회선에서는 큰 값의 존재는 사용되는 레디 스의 위치, 데이터의 양이 최대 한계 두보 하나의 스트링 값으로 다음이 긴급 큰 객체 분할 값을 초과한다.
데이터베이스를 유지하고 데이터베이스 업데이트에 두 번 같은 레디 스 쓰기, 삭제, 삽입, 키를 지정 레디 스에서 삭제하기 위해.
모든 기존의 작업을 레디 스하지만, 데이터베이스가 삭제되었다이 방법 @Transactional 열린 트랜잭션이, 키 조작을 레디 스하는 업데이트 방법에 묻혀있는 광산은 트랜잭션에 합류했다.
줄에 후 오류 :
그것을 분명하게 오류는 트랜잭션을 지원하지 않는 클러스터 모델을 레디 스. 클러스터가 텍스트를 참조 할 수 있습니다 트랜잭션을 지원하지 않는 이유는 : IS는 거기에 어떤 레디 스 클라이언트 (자바가 선호) 레디 스 클러스터에서 어느 지지대 거래?
이 질문을 바탕으로,이 문서에 요약되어
1, 트랜잭션의 봄
오류가 발생했을 때 모든 데이터 액세스 기술은 트랜잭션 메커니즘이 이러한 기술은 트랜잭션을 열 수있는 API를 제공, 트랜잭션이 전체 운영 데이터 또는 롤 백 데이터에 최선을 다하고 있습니다.
다른 데이터 액세스 기술의 문제를 해결하는 봄 통합 메커니즘, Spring은 트랜잭션 제공하는 PlatformTransactionManager
사용 인터페이스 인터페이스, 다른 데이터 액세스 기술을.
데이터 액세스 기술 | 실현 |
---|---|
JDBC | 의 DataSourceTransactionManager |
JPA | JPATransactionManager |
최대 절전 모드 | HibernateTransactionManager를 |
JDO | JdoTransactionManager가 |
분산 트랜잭션 | JtaTransactionManager를 |
SpringBoot 거래에서 열기가 매우 간단합니다, 바로 메소드 나 클래스에 코멘트에 @Transactional를 사용합니다.
봄 공식 문서는 @EnableTransactionManagement 열린 트랜잭션이 필요하지만, 자동으로 SpringBoot 우리가 할 수있었습니다으로 구성하는 그래서 SpringBoot이 코멘트에 작성하지
@Transactional 몇 가지 일반적인 속성에 따라 여기에 몇 가지 메모를 강조
번식
전파 메커니즘 문제, 주로 다음은, 기본이 필요합니다 :
- 필수 - 동일한 트랜잭션을 사용하여 새로운 트랜잭션 B의 메소드에 대한 호출이없는 경우 이상이 방법 B 롤백을 발생하면 방법 A는 트랜잭션을 호출, 전체 트랜잭션이 롤백됩니다.
REQUIRES_NEW는 - 메소드 A가 메소드 B를 호출하면 B는 데이터 A 롤백의 비정상적인 방법 발생하지 않도록 관계없이 문제가 있는지 여부의 새 트랜잭션을 엽니 다.
- NESTED - 그리고 REQUIRES_NEW 비슷하지만 단지 JDBC, 최대 절전 모드를 지원하거나 JPA는 지원하지 않습니다
- 지원 - 트랜잭션 메서드 호출을 사용하는 트랜잭션이 어떤 거래는 문제가 없습니다 것입니다
- NOT_SUPPORTED - 메소드 호출의 첫 번째 단계에서 트랜잭션이 보류중인 트랜잭션을 종료하는 경우 적용 방법은 트랜잭션 내에서 수행되지 않습니다.
- 결코 - 트랜잭션이 예외가 발생합니다 경우, 트랜잭션이 강제되지 수 없습니다
MANDATORY은 - 트랜잭션이 예외를 throw하지 않는 경우, 트랜잭션을 강제해야합니다
rollbackFor
기본적으로 롤백이 발생할 수있는 예외를 지정하는 것은의 Throwable의 서브 클래스
noRollbackFor
무엇 디폴트의 Throwable 실행의 서브 클래스, 비정상 트랜잭션 롤백을 사용할 수없는 원인
2, 거래의 실패의 경우 @ 트랜잭션
- 只对public方法生效。默认的protected和private方法上写上@Transactional不会报错,但该方法上的事务不生效,官方原文:Method visibility and @Transactional;
- 默认情况(只写@Transactional不填写rollbackFor参数)下此注解会对unchecked异常进行回滚,对checked异常不回滚;
- 类内部未开启事务的方法调用开启事务的方法
前两条很好理解,针对3,引用丁雪丰的《Spring全家桶》视频中的解释:
Spring的声明式事务本质上是通过AOP来增强了类的功能
Spring的AOP本质上就是为类做了一个代理看似在调用自己写的类,实际用的是增强后的代理类
下图描述了方法被事务代理时的流程,来源:Spring AOP
3、SpringBoot整合Redis事务实践
下面我们搭建一个最简单的SpringBoot整合redis的工程用代码来验证redis事务
SpringBoot整合Redis
SpringBoot整合redis使用的是spring-boot-starter-data-redis
,redis事务依赖于jdbc的事务管理,所以还需要引入jdbc
pom相关引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
开启Redis事务
编写redis配置类,开启redis事务,配置事务管理
@Configuration
public class RedisConfig {
@Bean
public StringRedisTemplate StringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
/**
* description 开启redis事务(仅支持单机,不支持cluster)
**/
template.setEnableTransactionSupport(true);
return template;
}
/**
* description 配置事务管理器
**/
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}
代码验证
针对本文讨论,设计了四个验证方法,可自行验证
/**
* description 不带事务set
* return java.lang.String
* author 郑晓龙
* createTime 2019/12/12 16:36
**/
@GetMapping("put")
public void put(String key, String value) {
redisService.put(key, value);
}
/**
* description 带事务set
* return java.lang.String
* author 郑晓龙
* createTime 2019/12/12 16:36
**/
@GetMapping("putWithTx")
public void putWithTx(String key, String value) {
redisService.putWithTx(key, value);
}
/**
* description 调用带事务方法不生效的情况
* return java.lang.String
* author 郑晓龙
* createTime 2019/12/12 16:36
**/
@GetMapping("invokeWithPutTx")
public void invokeWithPutTx(String key, String value) {
redisService.invokePutWithTx(key, value);
}
/**
* description 调用带事务方法生效的情况
* return java.lang.String
* author 郑晓龙
* createTime 2019/12/12 16:36
**/
@GetMapping("invokeWithPutTx2")
public void invokeWithPutTx2(String key, String value) {
redisService.invokePutWithTx2(key, value);
}
4、总结:
- redis事务只支持单机,不支持cluster
- 需要开启事务时,只需要在对应的方法或类上使用@Transactional注解即可,SpringBoot自动开启了@EnableTransactionManagement
- 需要注意事务不生效的几种情况
- redis事务依赖于jdbc的事务管理
5、示例代码及参考:
- Transaction Management
- Transaction Propagation
- Transactional Support
- 《Spring全家桶》丁雪丰