数据库变更管理与Jenkins管道优化指南
立即解锁
发布时间: 2025-08-13 01:02:44 阅读量: 14 订阅数: 13 


使用Docker和Jenkins实现持续交付的关键实践
### 数据库变更管理与Jenkins管道优化指南
#### 1. 数据库变更管理基础
在连续交付过程中,数据库的管理至关重要。以下是一个简单的求和服务示例代码:
```java
private CalculationRepository calculationRepository;
@RequestMapping("/sum")
String sum(@RequestParam("a") Integer a, @RequestParam("b") Integer b) {
String result = String.valueOf(calculator.sum(a, b));
calculationRepository.save(new Calculation(a.toString(), b.toString(), result));
return result;
}
```
启动服务可使用命令:`$ ./gradlew bootRun`。启动服务后,向 `/sum` 端点发送请求,每次求和操作都会记录到数据库中。若想浏览数据库内容,可在 `application.properties` 文件中添加 `spring.h2.console.enabled=true`,然后通过 `/h2-console` 端点访问。
#### 2. 连续交付中的数据库更新
在连续交付管道中更新数据库,一种常见方法是在迁移命令执行阶段添加更新步骤。但这种方法有两个明显缺点:
- **回滚问题**:数据库变更并非总能回滚(如 Flyway 完全不支持降级),服务回滚时数据库会变得不兼容。
- **停机问题**:服务更新和数据库更新不是同时执行,会导致停机。
这引出两个需要解决的约束:
- 数据库版本需始终与服务版本兼容。
- 数据库架构迁移不可逆。
#### 3. 向后兼容的数据库变更
向后兼容的变更相对简单。例如,假设数据库 v10 架构迁移是向后兼容的,若要回滚服务 v1.2.8 版本,部署服务 v1.2.7 即可,无需对数据库做任何操作(因数据库迁移不可逆,保留数据库 v11)。由于架构更新向后兼容,服务 v1.2.7 能与数据库 v11 完美配合。
下面是一个向后兼容变更的示例,为 `calculation` 表添加 `created_at` 列:
- **迁移文件 `src/main/resources/db/migration/V2__Add_created_at_column.sql`**:
```sql
alter table CALCULATION
add CREATED_AT timestamp;
```
- **`Calculation` 类添加新字段**:
```java
private Timestamp createdAt;
```
- **调整构造函数及在 `CalculatorController` 类中的使用**:
```java
calculationRepository.save(new Calculation(a.toString(), b.toString(), result, Timestamp.from(Instant.now())));
```
此变更为向后兼容,即使恢复 Java 代码并保留数据库中的 `created_at` 列,一切也能正常工作。
#### 4. 非向后兼容的数据库变更
非向后兼容的变更更具挑战性。若 v11 数据库变更不向后兼容,将无法将服务回滚到 1.2.7 版本。可将非向后兼容变更转换为在一定时期内向后兼容的变更,具体做法是将架构迁移分为两部分:
- 立即执行的向后兼容更新,通常意味着保留一些冗余数据。
- 在回滚期后执行的非向后兼容更新,回滚期定义了代码可回退的范围。
以删除列为例,步骤如下:
1. 在源代码中停止使用该列(v1.2.5,向后兼容更新,先执行)。
2. 从数据库中删除该列(v11,非向后兼容更新,回滚期后执行)。
再看重命名 `result` 列为 `sum` 的更复杂场景,步骤如下:
1. **添加新列到数据库**:
创建迁移文件 `src/main/resources/db/migration/V3__Add_sum_column.sql`:
```sql
alter table CALCULATION
add SUM varchar(100);
```
执行迁移后,会有 `result` 和 `sum` 两列。
2. **修改代码以使用两列**:
在 `Calculation` 类中修改:
```java
public class Calculation {
...
private String sum;
...
public Calculation(String a, String b, String sum, Timestamp createdAt) {
this.a = a;
this.b = b;
this.sum = sum;
this.result = sum;
```
0
0
复制全文
相关推荐










