α’αααααααααααααααααα’α·αα’αααΈαααααααααααΆααααα αΆααΆαααααααΆααααΌαααααΆααα·αααααααα αααα»αααΆαααΆααα±ααααααΎααααΆααα ααΎαααΉαααααΆααα’αααααΈα’αααΈαααα’αΆα ααΎαα‘αΎαα αααααααααα·ααΈααα·αααααααααα’ααα ααααα·αααΎα’αααααααΆααΆαααΆαααααααΆααααααααΆαααΆααααα αααΆαα»αα αααααΆααβααβααΎαβααΉαβααααβααΆααβααααΆααβααΆαβααααΎαβααΈαα·αβααααβαααααα·ααΈβαααβαααααΌαβα±ααβααΆαβαααβααααΆβαα·αβααααΎαααΆα (αααα αα ααααΌαα ααααααααα - ααΌααααααααααΆααα αΆα) ααααααααααααα·ααααα·ααΆαααααααΎαααΉαα’αα»ααααααΆαααααΆααααααΌαααΌαααααΆααα·ααααααααααα·αααααααΆααααααααααα»ααααααααααααααααΆαααααααα
ααααα·αααΎα’αααα
αααααααΈα§ααΆα αααααΌαααΈα’ααααα α’αααα’αΆα
ααααααααα½αααΆαα
ααα ααααΈααααΆα
ααΆαβααΆααβαααααΆαβαααβααααΆβαα·αβααααΎαααΆα
α’αααΈαααααΆα’αΆααααααΆαα ααΆαααΆαααααααΆαααααααααααΌααα? α’αααα’αΆα αα·ααΆαααΆαααΆαααααΊααΆαααααααααααα·ααΈααααα’αααααααΌαααΆαααΆααα±ααααααΎααααΆααααΆααααααααα’αααα’αΆα ααααΆαααααααααΈαααααααα·ααΈααααααααααααα»αααΆαααα·α αααααααααα’αααααααΎααααΆαααα·ααααααααΆααααΆααα·αα’αΆα ααααΎααΆαααααααΆα ααΆαααααααααααα’αααααααΎ αα·ααααα»αα αα»α αααααΊααΆααααΆααΈαααΌααααΆαααΆαααααααΆαααααα’αααα»ααααα’αΆα ααααΎαα ααΆα αααααααΆα’αα»ααααΆαα±αααααααααα·αααααααΈαααααΌαααΆαααααΆα αα·αααα α»αααααΌαααΆααα½ααα»αααααα·αααΆαααΆαααααΆαα
ααΎααααΎααΌα ααααα ααΎααααΈαααααα ααΆαααα? ααΆααα·ααΈααΆα αααΎα αααααΊααΆαα·ααΈαα½ααααα»αα αααααα·ααΈααΆαααααα
- ααΆαααααααΆαααααααα 1 ααααααΆααααααααα’αααα
- ααααΎααΆαααααΆααααααΌαααΌαααααΆααα·αααααα
- ααααΎαααα #2 ααααααΆααααααααα’αααααααααΆαα½ααααα #1
- αααΆαααΆα’αααααΎαααΆααααααα 2 ααααΎαααΆαααΌα αααααΆαα½ααα ααΌααα»αααααααα 1 α αα
- αα½α ααΆαα!
ααΆααααα½ααα? ααΆα’αα»αα ααΆαα·αααΆααααααααα α αΎαααΎαααΉααα·αα·αααααΎαααΆα±αααααα’α·ααα ααααααααα α₯α‘αΌαααα ααΌααα·αα·αααααΎαααααΎαααΆαααΆαααααααΆαααααααΆαα½ααααααααα - ααΆαααΆαααααααΆαααααααααααα
ααΎα’αααααααΆαα heard α’αααΈ
- ααααΌαααααΆααααΆα αααΆααα ααααααΈαααααΌαααα·αααααααααα’ααα ("ααα" αα·α "αααα") ααααΎαααΆαα
- ααΉαααΆαα ααΆα αααααΆααα’αααα ααΆααααα·ααααΆααααααα, i.e. ααΌα αααα URLs ααα·αααααα ααα’α»ααα ααΈααα;
- ααΆαααααααΆα αα·αααΆαααααααΆαααααΆααααααΌααααααα·ααΈααΆααα’αααα αααα»αααα·ααααΆαααααα
- ααααΌα url ααΈαααααααα ααα·ααααΆααααα
ααΆαβααΆααβαααααΆαβαααβααααβαααβααΊβααΆβαα·ααΈααΆαααααβαααβα’αα»ααααΆαβα±ααβα’αααβααΆααααα½αβααααΆαβαα»αααΆαβααααΈαβαααβαα·αβααΆα αβααΆααααβααΈβααΆαβαααααβααα·αααααα αααααΊαααααΆαααααΆααα·ααααααΆ αααααΈααΆααΆαα’αααΈαα½αααΎαα‘αΎαααααα α’αααα’αΆα αα·ααααααααα ααα·ααΆααΆαααΈαα»αααΆααααΆαααΆααααα½ααααααααΆαααα βα α»α αα·αααΎαβα
αααααΆααααΈααΆαα’αΆαααΆααα’ααααΆαααΎ α’αααα’αΆα ααΉααα½ααααα½αααΆ ααΎααααααααααααΆαααΆααααΆααααααΉαααΆαααΆαααααααΆααααααααααα?
ααΆααΆααααααΎαααΆαα αα½αααααΆαα
αααΎαααΌα
ααααΆ α
αΆααααΆααααΈααΆααααααΆααΆαααΌαα
αααΆααα
ααααααΈαααααα·ααααΆαααΌα
ααααΆααΆαααΆαα±ααααΆαααΆααα·αααααααΉαααααααααααααααα»αααΆααααααααΆαα½αααα αααβααΆβααΌαα ααα»βαααβαααα»αβααααβα’αα’αΆα
αααααΎααα½ααααααΊααααΎααΌαααααΆααα·ααααααααΌα ααααΆ αααααΎααα»αααΆαααααααααααααααααΆαααααααΆααααα ααααα αα·ααααα αα αααα»ααα·ααΈααΆαααααααα ααΆααΉαααΆααααΌαααααΆααα·ααααααα’αΆα ααΆααααα αΆ ααΆαα·ααααα ααααααα’αααααααΌαααΆαααααΆααααααΌααααααααΆαααααααααΆααΎααααΈααΆααααααααααααΈαααααααα·ααΈα
α αΎααα ααΈαααααΎαααααααααα αΆα αααααα αααα»αα’ααααααααα ααΌαααααΆααα·αααααα. ααΌααααα‘ααααΎαααααΆααααα½ααααα
ααααΎααΆαααααΆααααααΌαααΌαααααΆααα·ααααααα
α₯α‘αΌαα’αααααααΌααα½ααααα½αα―αααΌααααα½α - α α»αααΎααΆαααααΆααααααΌαααΌαααααΆααα·αααααααα·αααααΌαααααΆαα·α? ααΎβααααβαααααα·ααΈβααααΌαβααααβαααα»αβααΉαβαα·αβααΌα βα¬? ααΆααα·ααα ααααα·αααΆα’αααΈαααααΉαααΎαα‘αΎα...
ααΌα αααα αααααΈααΆααΆαα’αααααααααααααααααααΆαααΆαααααααΆαααΌααα/αααααααααααα αααααα»αα αα»αααΆααααααααΉαα’αα»ααααααΆαααααΎαααΆααααααΆααα»ααααα·ααΆαααΆααα»αααΆαααααααααααΆααααΆαααΆαααααααΆααααααα·ααΈαααααα½αααα
- αααα ααααα ααααΆαα½αααΉαααααααααΈαααααααα·ααΈ
- αα·ααααααα·ααΈααααααα»αααααΎαααΆα
- ααααΎαααΆαααααααΈαααΎααααΈαααααααΌαααααΆααα·αααααα
- ααΆαααααααΆα αα·αααΎαααααΎαααΆαααααααααΈαααααααα·ααΈ
αα αααα»αα’αααααααα ααΎαααΉααααααΆαααααα’α·αα’αααΈαααααααα’αααα’αΆα ααααΎααΆαααΆαα½αααΌαααααΆααα·αααααα αα·αααΌαααααα’ααα ααΎααααΈααΆαααα’αααααααααααααΈααΆαααΆααα±ααααααΎααααΆααααααΆαααααααααα
αααα αΆααΌαααααΆααα·αααααα
ααααα·αααΎα’αααααΆααααααα·ααΈααααΆαααααααααα·ααααααΆαα»ααα·ααααααααΆαα½ααα αααα»αααΌαααααΆααα·αααααα α’αααα’αΆα ααα½αααΆαααΌαααααΆαααΆαααααααΆαααααααααααααΆααα ααΆα’αα»αα αααααα·ααΈααΆαα αααΎαααααΌαααΆααααααΆαα»ααα·αααααααα ααααααααΆαα½αα αααααΆααΌαα ααα»αααα’ααααα½ααααα·αααΈααααα»ααααααααΎααΆαααααΆααααααΌαααΆαα½αα ααααααααααΈα αα»αααΉαααΎααααααααααααα’α·αα’αααΈααααααααΆααααααΌααααααααΆααα ααΎααααΈαα»αα±ααααΆαααΆαααααααΆαααααααααα’αΆα ααααΎαα ααΆα ααΌαααΎααααααααΎαααααααΆαααααααααΆαα»ααα·αα
αααααααΆααααααα
αα
αααα»αα’ααααααααααΎαααΉαααααΎ classpath:db/migration
) αα
ααΈαααα’αααα’αΆα
ααΎαααΎαα§ααΆα αααααα―αααΆαααΆαααααΎα
αααΆααααα»ααααααα
βββ db
βββ migration
βββ V1__init.sql
βββ V2__Add_surname.sql
βββ V3__Final_migration.sql
βββ V4__Remove_lastname.sql
αααα»αβα§ααΆα αααβααα ααΎαβααΎαβααααααΈαβααΆαβααααΆααβααΈβα
ααα½α 4 αααβααααα·αβααΎβαα·αβααααΌαβααΆαβααααα·ααααα·βααΈβαα»αβααΉαβααααΌαβααΆαβααααα·ααααα·βαα½αβαααααΆααβααΈβαααααβαααβαα
βαααβαααβαααααα·ααΈβα
αΆααβααααΎβαβα αααααΎαα―αααΆααα½α (V1__init.sql
) ααΆα§ααΆα αααα
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');
α’αααΈααααααααΆαααΊααΆααΆαααααααααααααα½αα―ααααΆαααα’α₯αααα
ααα α’αααα’αΆα
ααααΎ SQL ααΎααααΈαααααααΈαααααααααΌαααααΆααα·ααααααααααα’ααααα½αααααααΌαααΆαααααααα αααααΆααααααααΆαααααααα’αααΈ Spring Boot αα·α Flyway ααΌααα·αα·αααααΎα
αααααααΎα§αααααααααααααααααααααΆαα½α Spring Boot α’αααααα½αααΆαα’ααααααααααααα 2α
- α’ααααααααααΆαααααΆααααααΌαααΌαααααΆααα·ααααααααΈααΆαααααΆααααααΌαααΌα
- ααΆαααααΎα αααΆααααα»αααΌαααααΆααα·ααααααααΎαα‘αΎααα½αααΆαα½αααΉαααΆαααΆααα±ααααααΎαααΆααααααα·ααΈααααα’ααα αααααΊα§α ααααΎαααΆαααΆαααααααΆαααααα’αααααααΌαααΆαααααΎα±ααααΆαααα
ααΆααααααααΆααααα αΆααΌαααααΆααα·αααααα
αα αααα»αααααααααααΆααααα’ααααα ααΎαααΉααααααααΎααΆαααΎααα·ααΈααΆαααααααΈαα ααααααΆαααααΆααααααΌαααΌαααααΆααα·ααααααα
- ααΆααα·αααααααΆααΆαααααα
- ααΆαααααααΆααΆαααααα
ααΈαα½αααΉαααααΌαααΆαα αΆαααα»αααΆααΆααΆααααααΆααα½ααααα’ααααα·ααα½αα’αα»ααααααΆαααΆαααααααΆαααααΆααααααααΆααα αΆααααααααΆαααΆααααα αααΆαα»α... ααΈααΈααααααααΌααααααααααΆαα’αααΈαααααααα’αααα’αΆα α’αα»ααααααΆαααΆαααααααΆααααααααΆααααααααΆααα αΆα α αΎααααα»αααααααα½ααααααΆααΆαααααααΆαααααααα
ααααααααααααΎααααααΎαααΉαααααΎααΆαααΉαααααΆαααΆαααααα·ααΈ Spring Boot Flyway ααααΆαααααα½ααααααΆα Person
Ρ first_name
ΠΈ last_name
αα
αααα»αααΌαααααΆααα·αααααα (αααα αα ααΆαααααααα Person
ααΊααΆααΆααΆα αα·α first_name
ΠΈ last_name
- ααΆαααααααΊααΆααΆααα
αααα»αααΆα) ααΎαα
ααααααΌαααααα last_name
Π² surname
.
ααΆααααααα
αα»ααααααΎαα αΌααα αααα»αααααααΆααααα’α·α ααΆαααΆααααααααα½αα ααα½ααααααΎαααααΌαααααΎα’αααΈαααααα·ααΈααααααΎαα ααααααααααΆαααααααΎαα αααααααα ααΆαααΉαααΆααααΎαααΆαααααΆαααααα½αα
αααααααααΆααα α’αΆααΈααααα PRO-TIP α ααααΎαααΆαααΆααααα’αΆα αα½αα’ααααααααααααΆααααΆαα αααΎαααΎααΆαααΆαααα (ααα»αααααΆααααα αααΎααααα’αααααΆαααααΎααΆαα±αααααα»αα αα»αααααα’ααα ααααΆααααΆααααα αααΎαα’αααα’αΆα αααααααΆα)!
αα·αα αΆαααΆα ααααα‘ααααΌαααααΆααα·ααααααααα
ααΆαα½αααααα½ααααααααΎαααΆαααΆαααααααΆα (ααΆααα·ααααα‘αααααα·αααααΌαααααΆααα·αααααααα½αα ααα½αααΊααααΎααααα·αα’αΆα αα αα½α αα ααΌα ααΆααΆααα»αα‘αΎααα·α)α ααΎαα αααααα‘αααααααααα·ααΈααα»αααααα αα·ααΈααα αααααΈααΆα’αααααΆαααΌαααααΆααα·αααααααααααααααΆ (α§ααΆα ααα SQL αα·α NoSQL) αααααααΆαααααααΆαααααα’αααααΉαααΎααα ααΌα ααααΆα
ααΆααααΌαααα’αΆα ααααΎαα ααΆαααΎααααΈαααααααααα·ααΈαααα‘αααααα·ααααααα½ααααα‘αααααα·α (αα·αααΆαααααα)
Rollback αα½αβααβααααΌαβααΆαβααααΎβαα βαααβα αΆαααΆα αα ααααα·αααΎααΆαααα α»ααα αααα»ααααααα αα α»ααααααααααα·αααααΌαααΆααα½ααα»ααααΆαααΆααααα½αααα ααΎααα½αααα’αΆα αααα‘αααα αααααααααααΎαααΆαα α»αααααααααα»αα ααΎαααααααααΆααααα α»αααααααααα»ααααααΊααΆαααααα»αα ααΆααααααΆααΆαααααΌαααααΆααααΌα αα·αααΌαααααΆααα·αααααααααααΆααααΆαα ααααααΆαα αααΎαααΆααα½αααΉααα·ααΆα αα·αααααααΆααα
αααααααααΆαα. ααΎααααΈα±ααααΆααααααΆααααα½αα’αΆα αα αααα»αα’αααααααα ααΎαααΉαααααΆααααααΌαααααααααΆααααααααααα·ααΈα
ααα αΆαααΈ 1: ααααΆαααΆαααααΌα
αααααααααα·ααΈα 1.0.0
αααα DBα v1
ααΆαα’ααααΆαα·ααααΆα
αααααΉαααΆααααΆαααΆαααααΌααααααααα·ααΈα
ααΆαααααΆααααααΌαααΌαααααΆααα·αααααα
DB ααΆα last_name.
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');
ααΆαααααΆααααααΌααααααΌα
αααααα·ααΈαααααΆαα»ααα·αααααααα»αααααα
αααα»α last_name
:
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastname) {
this.lastName = lastname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName
+ "]";
}
}
ααΆαααααΌαααααααα½ααααα·αααααααΆααααααα
ααΌααααα‘ααααΎαα§ααΆα αααααααααααααΌαααααααα½αααα
ααΆαααα α·ααααα»αααΆααα α§ααΆα αααααΆααααααααΉαααααΎα±ααααΌα α’αααΈααααα ααααΆα ααΎααααα αΆαααΆααΎααααΈαααα αΆαααΈαααα αΆααααΆαααααααΆααααΌαααααΆααα·ααααααα
αααααααααα·ααΈα 2.0.0.BAD
αααα DBα v2bad
ααΆαα’ααααΆαα·ααααΆα
ααΆαααααΆααααααΌααα αα α»αααααααα·αα’αα»ααααΆαα±ααααΎαααααΎαααΆαα§ααΆα αααααΈα (α αΆαα αα·αααααΈ) αααα»αααααααα½αααα ααΌα ααα ααΆαααΆαααααααΆαααααΆααααααα αΆαααΉααα·ααΆααααααα ααΆα (ααααα·αααΎααΆαααααααααααΌαααΆααααααα·α αΆαααΆ ααΆαα·αααΆαα·αα’αΆα αα αα½α αα)α
ααΆαααααΎααααα A/B
ααααΆαααΆααα
αα
α»ααααααααΊααΆααΎαααΆααααααααααα·ααΈ 1.0.0,
ααΆαααααααΆααα
αααα»αααα·ααααα αα·αααΌαααααΆααα·αααααα v1
. ααΎαααααΌαααααΎα§ααΆα αααααΈααΈααααααααα·ααΈ αααα 2.0.0.BAD
αα·αααααΎαα
αα
α»ααααααααΆαααΌαααααΆααα·αααααααα
v2bad
.
ααα αΆαα
- αααααα·ααΈααααααααΈααααΌαααΆαααΆαααααααΆα
2.0.0.BAD
αααααααΎαα αα α»ααααααααΆαααΌαααααΆααα·ααααααααv2bad
- αα
αααα»αααΌαααααΆααα·αααααα
v2bad
αα½αααlast_name
αα·αααΆαααααα - ααΆααααΌαααΆαααααΌαααsurname
- ααΆαααααΎαα
αα
α»ααααααααΆαααΌαααααΆααα·αααααα αα·ααααααα·ααΈααΆααααααα α αΎαααααΈαα½αα
ααα½ααααα»αααααΎαααΆα
1.0.0
, α’ααααααααααα - αα αααα»α2.0.0.BAD
. α’αααΈααααααααΆαααααΌαααΆαααααΆαααα ααΌαααααΆααα·ααααααv2bad
- ααααΈααΆααα’αααααααα
1.0.0
ααΉαα αΆααααααΎααααα ααααα α»α ααααααα½αααααΉαααααΆααΆααααα αΌααα·αααααααα αααα»ααα½αααlast_name
ααααα·αααΆαααααα - ααααΈααΆααα’αααααααα
2.0.0.BAD
ααΉαααααΎαααΆααααααααΆααααα αΆ
ααΌα αααα’αααα’αΆα ααΎαααΎα ααααα·αααΎααΎαααααΎααΆαααααΆααααααΌααα·αααααααΆαααααααα ααααααΌαααααΆααα·αααααα αα·ααααααα·ααΈααα ααΆαααααΎααααα A/B ααΊαα·αα’αΆα αα αα½α ααα
ααΆαβαααα‘ααβαααααα·ααΈβ
α
αΌααααααααΆαααααΆααααΈααααΆααΆαααααΎ A/B ααΆαααααααΆα (αααα αα per.: α’ααααα·αααααααα ααααΆααΆααααααΆααΆαααααΎααααα A/B αα
ααΈααα) ααΎαααΆααααααα
α
α·αααααΆααΎαααααΌαααααα·ααααααα·ααΈαα
αααα 1.0.0.
α§αααΆααΆααΎααα·αα
αααααα‘ααααΌαααααΆααα·ααααααααα
ααα αΆαα
- ααΎααααααααααααα·ααΈαααα
2.0.0.BAD
- ααΌαααααΆααα·αααααααα
ααααΆα
v2bad
- α
αΆααααΆααααΈαααα
1.0.0
αα·ααααααΆααΆααΆα’αααΈsurname
ααΎαααΉαααΎαααα α»α - αααβααΆαβαααβααααΆα ααΎαβαα·αβα’αΆα βαααα‘ααβαα βαα·αβααΆαβαααβααα
ααΌα αααα’αααα’αΆα ααΎα ααααα·αααΎααΎαααααΎααΆαααααΆααααααΌααα·αααααααΆαααααααα ααααααΌαααααΆααα·αααααα αα·ααααααα·ααΈααα ααΎααα·αα’αΆα αα·ααααααααα αααααα»αααΆαααα
αααααα ααα»ααΆαααααα·ααααα·ααααααΈα
Backward incompatible scenario:
01) Run 1.0.0
02) Wait for the app (1.0.0) to boot
03) Generate a person by calling POST localhost:9991/person to version 1.0.0
04) Run 2.0.0.BAD
05) Wait for the app (2.0.0.BAD) to boot
06) Generate a person by calling POST localhost:9991/person to version 1.0.0 <-- this should fail
07) Generate a person by calling POST localhost:9992/person to version 2.0.0.BAD <-- this should pass
Starting app in version 1.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:
{"firstName":"b73f639f-e176-4463-bf26-1135aace2f57","lastName":"b73f639f-e176-4463-bf26-1135aace2f57"}
Starting app in version 2.0.0.BAD
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:
curl: (22) The requested URL returned error: 500 Internal Server Error
Generate a person in version 2.0.0.BAD
Sending a post to 127.0.0.1:9995/person. This is the response:
{"firstName":"e156be2e-06b6-4730-9c43-6e14cfcda125","surname":"e156be2e-06b6-4730-9c43-6e14cfcda125"}
ααΆαααααΆααααααΌαααΌαααααΆααα·αααααα
ααααααΈααααααααααααααααααΌαααααα last_name
Π² surname
αααααααααααΈα Flywayα
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');
ααααααΈααααααααΌαααααα last_name
.
-- This change is backward incompatible - you can't do A/B testing
ALTER TABLE PERSON CHANGE last_name surname VARCHAR;
ααΆαααααΆααααααΌααααααΌα
ααΎαααΆαααααΆααααααΌααααααααΆα lastName
αα
ααΎ surname
.
ααΆαααααΌαααααααα½αααααΆααααααααααααΌαααααΆααΉαααααααα
αααααΊααΆααααΆαααΆαααΌαα αααα»ααααααΎαα’αΆα αα½ααααααα ααΎαααααΌαααααΎααΆαααααΆααααααΌαααααα·αααααααΆαααααααα ααΎαβααΆαβαααα αΆαβαα½α βα αΎαβααΆβαααααΆααβααΆαβααΆααβαααααΆαβαααβααααΆβααΌααα ααΎαβαα·αβαα½αβα’αα»ααααβααΆαβααααΆααβααααΌαβααΌαααααΆαβαα·ααααααβαααβααααΆαβααα αΆαβααααααβαααβααα αα αααα»ααααααααα’αααααααα ααΎαααΉαα’αα»ααααααΆαααΆαααααααΆααααααα·ααΈα ααα½α 3 αα½αααΆαα½αααΉαααΆαααααΆααααααΌαααΌαααααΆααα·αααααα ααΎααααΈαααααα ααΆαααΌααααααααααα ααααΆα ααααααααααααααΆααΆαααΌαααΆαααααααΆαααααααα
αααααααααΆααα ααΌαα αΆαααΆααΎαααΆαααΌαααααΆααα·αααααααααα
v1
. ααΆααΆααα½αααfirst_name
ΠΈlast_name
. ααΎαααααΌαααααααΆααααααΌαlast_name
αα ααΎsurname
. ααΎαααααΆααααααααααα·ααΈαααααα1.0.0,
ααααα·αααΆααααααΎsurname
.
ααα αΆαααΈ 2: ααααααααΆααααααΌα
αααααααααα·ααΈα 2.0.0
αααα DBα v2
ααΆαα’ααααΆαα·ααααΆα
ααΆααααααΆααααααααα½αααααααΈ αα·αα ααααααΆαα·ααΆααααααΆ ααΎααααααΎαααΆαααααΆααααααΌαααΌαααααΆααα·αααααααααααααΌαααααΆααΉααααααααα αααα»ααααααΆαα½αααααΆααα ααααα·αααΎααΎαααααα·α JAR α¬ααΆα JAR α αΆααααααααα»αααααΎαααΆα ααΆααΉααα·αααΌα ααα‘α»ααααααααα·ααααα·αααααα
ααΎααααα»αααΆααα ααααααααααΈα
ααα αΆαα
- ααααΎααΆαααααΆααααααΌαααΌαααααΆααα·αααααα ααΎααααΈαααααΎααα½αααααααΈα
surname
. α₯α‘αΌαααααααα DB ααααα’ααααv2
- α
αααααα·ααααααααΈ
last_name
Π²surname
. ααα α·ααααα»αααΆααααΆβααΎβα’αααβααΆαβαα·ααααααβαααβα αααΎα α’αααβαα½αβααβαα·α αΆαααΆβααΆαβααααΎβα αααΆαβαααα»αβααΆβαααα»α! - αααααααΌααααααααααααααααΎ ααΆααααΈα ΠΈ Π½ΠΎΠ²ΡΠΉαα·α α
αΆαα αα½αααα α₯α‘αΌαααααααααααααα·ααΈααααα’αααα
2.0.0
- α’αΆααααααααΈαα½ααα
surname
ααααα·αααΎααΆαα·αααααααnull
α¬ααΈ last_name
ααααα·αααΎαα½αsurname
αα·αααΆααααααΆααα α’αααα’αΆα αα»αααΆααgetLastName()
ααΈααΌααααααααΆααΉαα ααnull
αα ααααααα‘αααααααα·ααΈααααα’αααααΈ3.0.0
αα αΌαααααα2.0.0
.
ααααα·αααΎα’ααααααα»αααααΎ Spring Boot Flyway ααα αΆαααΆααααΈααααααΉαααααΌαααΆαα’αα»ααααααα‘α»ααααα
αΆααααααΎααααα 2.0.0
αααααα·ααΈα ααααα·αααΎα’αααααααΎαααΆαα§αααααααααααΌαααααΆααα·ααααααααααα α’αααααΉαααααΌαααααΎααΏαααΈααααααααααΆααΎααααΈααααΎααΆ (ααααΌαααααΎαα
αα
α»ααααααααΆααααα db ααααα α αΎααααααΆααααααΆααα±ααααααΎααααΆαααααααα·ααΈααααΈ)α
ααΆααααΆααααΆααα α αα αΆαααΆαα½ααααααααΆααααααΎαααααΈα αα·αβαα½α ααΎααααΈα±ααααΆαα αα·αααααα. ααααα·αααΎα’αααααααΎ rollback αααααα·ααΈα αΆαααα·αααΉαα’αααΈαα½αααααααΈ α αΎαααΉααα·αααα‘αΎαααΆα’αα‘α»αααα
Insert.
ααα»ααααααααα·αααΎα’αααααααααα§ααααααααα αΎα db ααααα’αααααΉαααΆαv2
ααΆααΉααααααΌαα±αααααααααααααααα½αααααααΈα αααααΉαααΆαα±ααααΆαααΆααααααααΎααΆαααΉααααααΉααααΆααααΆααααΆααα α’αααααααΌααααα·ααΈααΆαααααα αα
getLastName()
ααΈααααααα αααα»ααααα3.0.0
αα·αααΆααααα·ααααα½ααααα αααα»αααΌααααlast_name
. αααααΆααααααΆ null ααΉαααααΌαααΆαααααααα ααΈαααα α’αααα’αΆα αα»ααα·ααΈααΆααααα α αΎαααααααααΆααααα½ααα·αα·αααnull
ααα»αααααααααααααΆαααα’ααΆαααα ααΊααααΌαααααΎα±ααααααΆααααΆαα αααα»ααααααα·ααααΆgetSurname()
α’αααααΆαααααΎαααΎαααααααα·αααΌαααααααΉαααααΌαα
ααΆαααααΎααααα A/B
ααααΆαααΆααα
αα
α»ααααααααΊααΆααΎαααΆααααααααααα·ααΈ 1.0.0
ααΆαααΆαααααααΆαααΎααΆαααα·α αα·αααΌαααααΆααα·αααααααα
αααα»α v1
. ααΎαααααΌαααΆαααααααΆαα§ααΆα αααααΈααΈααααααααα·ααΈαααα 2.0.0
αααααΉαααααΎαα
αα
α»ααααααααΆαααΌαααααΆααα·αααααααα
v2
.
ααα αΆαα
- αααααα·ααΈααααααααΈααααΌαααΆαααΆαααααααΆα
2.0.0
αααααααΎαα αα α»ααααααααΆαααΌαααααΆααα·ααααααααv2
- αααα»αααααααααααΎαα½αα
ααα½αααααΌαααΆαααααΎαααΆαααααααααααα
1.0.0
- ααΆαα’αΆαααααααΆααααααα α αΎαα’αααααΆααααααα·ααΈααααααΆα
αααΎαααααααα»αααααΎαααΆα
1.0.0
αα·αααααααααααααα2.0.0.
ααα»ααααααααααααΆααΆααααααΆαα½αααΌαααααΆααα·αααααααα αααα»αv2
- αααα
1.0.0
αα·αααααΎαα½αααααΆααααααΌααα αααα»αααΌαααααΆααα·αααααααα ααα»αααααααα2.0.0
ααααΎααααΆααα αα½ααααα·αααααααααααααααΆαα αα·ααα ααα αΎααα·ααα½αααΆαααα α»αααα - αααα
2.0.0
αααααΆαα»ααα·ααααααααΆαααααα»ααα½αααα αΆαα αα·αααααΈ ααΆααΆααΆαααααααΆααααααα
ααΆααααΆααααΆααα ααααα·αααΎα’αααααΆααααα½αααΆαα½ααααααΆααααΆαα»αααααα’ααααΎαααααααΈαα½αααα αΆαα/ααααΈ α’ααααα½αααα αα αΆαααΆα₯α‘αΌααααα’αααααΆαααααααααα½α (ααΆαα αααΎαααααααΆαα½ααααα ααααααΆααααααΌα)α α§ααΆα ααα ααααα·αααΎα’αααα ααααΆααα ααα½αα’αααααααΎααααΆαααααααΆαααΆααααααΌα (α’αααΈααααααααα α ααΆαα½ααα) ααΆαα αΆααααααΎααααα’αααα
A
αααααΆαααααα αΌααααααΆαααααααα·ααααααααααΌαααΆααααα αα (old
βnew
column) α’αααα’αΆα ααΆααα·αααααααα·ααααΈαααααΆααααααΆ ααααα·αααΎα’ααααα½ααα½αααααααΈα
ααΆαβαααα‘ααβαααααα·ααΈβ
α₯α‘αΌααααααΎαααΆααααααααααα·ααΈ 2.0.0
αα·αααΌαααααΆααα·αααααααα
αααα»α v2
.
ααα αΆαα
- αααα‘αααααααα·ααΈααααα’ααααα
ααΆαααα
1.0.0
. - αααα
1.0.0
αα·αααααΎαα½ααααααα»αααΌαααααΆααα·αααααααααsurname
ααΌα αααα rollback αα½αααααα½αααΆααααααα
ααΆαααααΆααααααΌα DB
ααΌαααααΆααα·ααααααααΆααα½ααααααααΆαααααα last_name
.
αααααααααααΈα Flywayα
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');
ααααααααααααΈα surname
.
ααΆαααα α·ααααα»αααΆααα ααΌαα αα αΆαααΆα’ααααα·αα’αΆα ααααααα§αααααααααα·ααααααΆ NULL αα αααα»ααα½ααααααα’ααααααα»αααααααααΆαααα ααααα·αααΎα’ααααααα‘αα JAR αα·α ααααα αΆααααΉααα·αααΆααααα·αα’αααΈαα½ααααααααΆααααααααα α αΎαααΉααααααααΆαααααααααααααααα·αα ααΆ NULL α ααααα·αααΎααΆαααΆαααααααααααα αααααα·ααΈα αΆααααΉαααΌα α
-- NOTE: This field can't have the NOT NULL constraint cause if you rollback, the old version won't know about this field
-- and will always set it to NULL
ALTER TABLE PERSON ADD surname varchar(255);
-- WE'RE ASSUMING THAT IT'S A FAST MIGRATION - OTHERWISE WE WOULD HAVE TO MIGRATE IN BATCHES
UPDATE PERSON SET PERSON.surname = PERSON.last_name
ααΆαααααΆααααααΌααααααΌα
ααΎααααααΆαα»ααα·ααααααααΆ last_name
αα·ααααα»α surname
. αααα»ααααααΆαα½αααααΆαααααΎαα’αΆαααΈ last_name
α
αΆααααΆααααΈαα½ααααααααΊααΆααααααααααα»αα αααα»αα’αα‘α»ααααααααΎαααΆαααΆαααααααΆα ααααΎαα½αα
ααα½αα’αΆα
ααααΌαααΆαααααΎαααΆααααα§ααΆα ααααααααα·ααΈααααα·αααΆααααααΌαααΆαααααΎαα
αα
α»ααααααααΆαα
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
private String surname;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* Reading from the new column if it's set. If not the from the old one.
*
* When migrating from version 1.0.0 -> 2.0.0 this can lead to a possibility that some data in
* the surname column is not up to date (during the migration process lastName could have been updated).
* In this case one can run yet another migration script after all applications have been deployed in the
* new version to ensure that the surname field is updated.
*
* However it makes sense since when looking at the migration from 2.0.0 -> 3.0.0. In 3.0.0 we no longer
* have a notion of lastName at all - so we don't update that column. If we rollback from 3.0.0 -> 2.0.0 if we
* would be reading from lastName, then we would have very old data (since not a single datum was inserted
* to lastName in version 3.0.0).
*/
public String getSurname() {
return this.surname != null ? this.surname : this.lastName;
}
/**
* Storing both FIRST_NAME and SURNAME entries
*/
public void setSurname(String surname) {
this.lastName = surname;
this.surname = surname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName + ", surname=" + this.surname
+ "]";
}
}
ααα αΆαααΈ 3: ααΆααααααααα α»ααααααα ααααΈαααααΌα
αααααααααα·ααΈα 3.0.0
αααα DBαv3
ααΆαα’ααααΆαα·ααααΆα
α
αααΆα per.: ααΆααααααα αα
αααα»αα’αααααααΎα α’ααααα·ααααααΆαα
ααααα’ααααααααααα»αααααααα
ααα‘αααΈααα αΆαααΈ 2α αα
ααα αΆαααα ααΆαααααΆααααααΌααα½αααααααΌαααΆαααααΎα‘αΎααα
αααα»αααΌααααααα·ααΈαααααΆαααααααααα»ααα»αααΆααααααααΎαα½αααα
ααα last_name
.
ααΆααααααΆααααααααα½αααααααΈ αα·αα ααααααΆαα·ααΆααααααΆ ααΎαααΆααααααΎαααΆαααααΆααααααΌαααΌαααααΆααα·αααααααααααααΌαααααΆααΉααααααααα ααααα ααααα·αααΎααΎαααααα·α JAR α¬ααΆα JAR α αΆααααααααα»αααααΎαααΆα ααΆααΉααα·αααΌα ααα‘α»ααααααααα·ααααα·αααααα
ααΆαβαααα‘ααβαααααα·ααΈβ
αα
αα
α»ααααααααΎαααΆααααααααααα·ααΈ 3.0.0
αα·αααΌαααααΆααα·αααααα v3
. αααα 3.0.0
αα·ααααααΆαα»ααα·αααααααα
last_name
. αααααΆααααααΆαα
αααα»α surname
ααααααΆαα
α»αααααααααα»αααααΌαααΆααααααΆαα»αα
ααα αΆαα
- αααα‘αααααααα·ααΈααααα’ααααα
ααΆαααα
2.0.0
. - αααα
2.0.0
ααααΎααααΆαα αα·αlast_name
ΠΈsurname
. - αααα
2.0.0
ααΉαααsurname
ααααα·αααΎααΆαα·ααααααΆααΌααα ααΎαα·αααΌα αααααα -last_name
ααΆαααααΆααααααΌαααΌαααααΆααα·αααααα
αα·αααΆαααΆαααααΆααααααΌααα ααΆαααααααααα αααα»αααΌαααααΆααα·ααααααααα ααααααΈαααΆααααααααααΌαααΆαααααα·ααααα· ααΎααααΈααααΎααΆααααααα α»αααααααααα·ααααααα αΆααα
-- WE'RE ASSUMING THAT IT'S A FAST MIGRATION - OTHERWISE WE WOULD HAVE TO MIGRATE IN BATCHES
-- ALSO WE'RE NOT CHECKING IF WE'RE NOT OVERRIDING EXISTING ENTRIES. WE WOULD HAVE TO COMPARE
-- ENTRY VERSIONS TO ENSURE THAT IF THERE IS ALREADY AN ENTRY WITH A HIGHER VERSION NUMBER
-- WE WILL NOT OVERRIDE IT.
UPDATE PERSON SET PERSON.surname = PERSON.last_name;
-- DROPPING THE NOT NULL CONSTRAINT; OTHERWISE YOU WILL TRY TO INSERT NULL VALUE OF THE LAST_NAME
-- WITH A NOT_NULL CONSTRAINT.
ALTER TABLE PERSON MODIFY COLUMN last_name varchar(255) NULL DEFAULT NULL;
ααΆαααααΆααααααΌααααααΌα
α
αααΆα per.: ααΆααα·αααααΆαααααα»ααααααααααΌαααΆαα
ααααα
ααα‘ααααα’ααααα·ααααααΈααα αΆαααΈ 2α αααα’αα»αααααΆααααααα·ααααΆααα’ααααα ααΆαααααΆααααααΌαααΌααα
ααα αΆαααααα½αααααΆααααααααααα
ααααΈααΆαα»αααααααΎαααΆαααΆαα½ααα½αααα last_name
.
ααΎααααααΆαα»ααα·ααααααααΆ last_name
αα·ααααα»α surname.
ααΎαααΈααααααααΎαα’αΆαααΈαα½ααα last_name
αααααααΆααΆααααααααααα»αα αααα»αα’αα‘α»ααααααααΎαααΆαααΆαααααααΆα ααααΎαα½αα
ααα½αα’αΆα
ααααΌαααΆαααααΎαααΆααααα§ααΆα αααααααα·αααΆααααααΌαααΆαααα‘αΎαααααα
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String surname;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurname() {
return this.surname;
}
public void setSurname(String lastname) {
this.surname = lastname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", surname=" + this.surname
+ "]";
}
}
ααα αΆαααΈ 4: ααΆααααααααα α»ααααααα ααααΈααΌαααααΆααα·αααααα
αααααααααα·ααΈα 4.0.0
αααα DBα v4
ααΆαα’ααααΆαα·ααααΆα
αααααΆαααααΆααα·ααααααΆαααααΌααααα 3.0.0
αα·αααΆαααααΎαα½αααααα last_name
ααααΆαα’αααΈα’αΆαααααααΉαααΎαα‘αΎααααα»αα’αα‘α»ααααααααα·ααααα·αα ααααα·αααΎααΎααααααααα
3.0.0
αααααΆααααΈαααα½αααα
ααααΈααΌαααααΆααα·ααααααα
αααααα ααα»ααΆαααααα·ααααα·ααααααΈα
We will do it in the following way:
01) Run 1.0.0
02) Wait for the app (1.0.0) to boot
03) Generate a person by calling POST localhost:9991/person to version 1.0.0
04) Run 2.0.0
05) Wait for the app (2.0.0) to boot
06) Generate a person by calling POST localhost:9991/person to version 1.0.0
07) Generate a person by calling POST localhost:9992/person to version 2.0.0
08) Kill app (1.0.0)
09) Run 3.0.0
10) Wait for the app (3.0.0) to boot
11) Generate a person by calling POST localhost:9992/person to version 2.0.0
12) Generate a person by calling POST localhost:9993/person to version 3.0.0
13) Kill app (3.0.0)
14) Run 4.0.0
15) Wait for the app (4.0.0) to boot
16) Generate a person by calling POST localhost:9993/person to version 3.0.0
17) Generate a person by calling POST localhost:9994/person to version 4.0.0
Starting app in version 1.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:
{"firstName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2","lastName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2"}
Starting app in version 2.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:
{"firstName":"e41ee756-4fa7-4737-b832-e28827a00deb","lastName":"e41ee756-4fa7-4737-b832-e28827a00deb"}
Generate a person in version 2.0.0
Sending a post to 127.0.0.1:9992/person. This is the response:
{"firstName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","lastName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","surname":"0c1240f5-649a-4bc5-8aa9-cff855f3927f"}
Killing app 1.0.0
Starting app in version 3.0.0
Generate a person in version 2.0.0
Sending a post to 127.0.0.1:9992/person. This is the response:
{"firstName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","lastName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","surname":"74d84a9e-5f44-43b8-907c-148c6d26a71b"}
Generate a person in version 3.0.0
Sending a post to 127.0.0.1:9993/person. This is the response:
{"firstName":"c6564dbe-9ab5-40ae-9077-8ae6668d5862","surname":"c6564dbe-9ab5-40ae-9077-8ae6668d5862"}
Killing app 2.0.0
Starting app in version 4.0.0
Generate a person in version 3.0.0
Sending a post to 127.0.0.1:9993/person. This is the response:
{"firstName":"cbe942fc-832e-45e9-a838-0fae25c10a51","surname":"cbe942fc-832e-45e9-a838-0fae25c10a51"}
Generate a person in version 4.0.0
Sending a post to 127.0.0.1:9994/person. This is the response:
{"firstName":"ff6857ce-9c41-413a-863e-358e2719bf88","surname":"ff6857ce-9c41-413a-863e-358e2719bf88"}
ααΆαααααΆααααααΌα DB
ααΆαααα v3
ααΎαααααΆαααααααα½αααα
αα last_name
αα·αααααααααΆαααΉααααααΉααααααΆααα
-- REMOVE THE COLUMN
ALTER TABLE PERSON DROP last_name;
-- ADD CONSTRAINTS
UPDATE PERSON SET surname='' WHERE surname IS NULL;
ALTER TABLE PERSON ALTER COLUMN surname VARCHAR NOT NULL;
ααΆαααααΆααααααΌααααααΌα
αα·αααΆαααΆαααααΆααααααΌαααΌαααα
ααα ααααΈααααα·ααααΆα
ααΎαααΆαα’αα»ααααααΆαααααΆααααααΌαααααααα½αααααααα·αααααααΆαααααααααααααααα αααα’αα»ααααααΆαααΆαααααααΆααααααααααΆαααααααααΆα αααΎαα ααΆαααααααααααΆααα ααααΈαααααααααααααααΆααααααΆαα’αα»ααααα
- ααΆαααΆααα±ααααααΎααααΆαααααααααααα·ααΈ
1.0.0
Ρv1
αααααααΆαααααΌαααααΆααα·αααααα (ααααααα½ααα =last_name
) - ααΆαααΆααα±ααααααΎααααΆαααααααααααα·ααΈ
2.0.0,
ααααααααΆαα»ααα·αααααααα αααα»αlast_name
ΠΈsurname
. αααααα·ααΈα’αΆαααΈlast_name
. ααΌαααααΆααα·ααααααααΊαα αααα»αααααv2
ααΆααα½αααααΌα ααΆlast_name
, αα·αsurname. surname
ααΊααΆα αααΆααα αααααα last_name
. (α αααΆαα αα½αβααβαααβαα·αβααααΌαβααΆαβααααα·αβαα·αβαα»αβααΆβααααβαα) - ααΆαααΆααα±ααααααΎααααΆαααααααααααα·ααΈ
3.0.0
ααααααααΆαα»ααααα·αααααααα αααα»αsurname
αα·αα’αΆαααΈααΆααααααΌαα αααααΆααααΌαααααΆααα·αααααα ααΆαααααΎα αααΆααααα»αα α»αααααααααα»αααΎαα‘αΎαlast_name
Π²surname
. αααααααααααααα αα·αααααα ααα ααααΈlast_name
. α₯α‘αΌαααα ααΌαααααΆααα·αααααααααα·ααα αααα»αααααv3
- ααΆαααΆααα±ααααααΎααααΆαααααααααααα·ααΈ
4.0.0
- αα·αααΆαααΆαααααΆααααααΌαααΆαα½αα αααααααααΌαααα ααΆαααΆαααααααΆαααΌαααααΆααα·ααααααv4
αααααα ααlast_name
. αα ααΈαααα’αααα’αΆα ααααααα§ααααααααααΆαααα ααΌαααααΆααα·ααααααα
αααααααΎααΆααα·ααΈααΆαααααααα α’ααααααααα’αΆα αααα‘αααααααα½ααα·αααααα·ααααααααΆαααααααΆααααΌαααααΆααα·αααααα/αααααα·ααΈα
αααααΌα
ααΌαααΆααα’αααααααααΎαααα»αα’ααααααααααΆααα
αααααα
αααααΆααααΈααααΌαααααΆαα α’αααααΉαααΎααα ααΆααααααααααααΆααααααα
βββ boot-flyway-v1 - 1.0.0 version of the app with v1 of the schema
βββ boot-flyway-v2 - 2.0.0 version of the app with v2 of the schema (backward-compatible - app can be rolled back)
βββ boot-flyway-v2-bad - 2.0.0.BAD version of the app with v2bad of the schema (backward-incompatible - app cannot be rolled back)
βββ boot-flyway-v3 - 3.0.0 version of the app with v3 of the schema (app can be rolled back)
βββ boot-flyway-v4 - 4.0.0 version of the app with v4 of the schema (app can be rolled back)
ααααααΈα
α’αααα’αΆα ααααΎαααΆαααααααΈααααααΆααα·αααααΆαα αααα»αααααααΈαααΆαααααα αααααΉααααα αΆαααΈααΆαααααΆααααααΌααααααααααΆααααααα αα·ααα·αααααΌαααααΆαα ααΉαααΌαααααΆααα·ααααααα
α ααβααΎα ααααΈβαααβααΆαβααΆαβααααΆααβααααΌβαβααααΌαβααααΆβααβαααααβαααα
./scripts/scenario_backward_compatible.sh
αα·αααΎααααΈααΎα ααααΈβαααβααΆαβααΆαβααααΆααβααααΌβαβαα·αβααααΌαβααααΆβααβαααααβαααα
./scripts/scenario_backward_incompatible.sh
Spring Boot Sample Flyway
α§ααΆα αααααΆααα’ααααααΌαααΆαααα
ααααΈ Spring Boot Sample Flyway.
α’αααα’αΆα
ααΎα http://localhost:8080/flyway
ααΆααααααΈααααααΈαα
α§ααΆα αααααααααα½ααααα
αΌααα»αααΌα H2 (αα
http://localhost:8080/h2-console
) ααΌα
ααααα’αααα’αΆα
ααΎαααααΆαααΆαααΌαααααΆααα·αααααα (ααααΆαααΎα jdbc URL ααΊ jdbc:h2:mem:testdb
).
ααΎαααΈαααααα
ααααΆαααΆααααααα’ααΌαααααΆααα·αααααα ααΆαααΉααααααΌααααα
ααΌαα’αΆαα’ααααααααααααααα ααΎαααααααααααΎααααααα
Kubernetesα α ααα»α’αααΈααΆαααΆααΆααΆαααΆααααααΆααααααΆααααΆαααααα»αααΆαααααααα ααΆααααααααααΆααααααααααααααΆααααααααα? ααααα Tekton - ααααααααα αΌααααααααΎα Kubernetes ααΆααααΆααααΌαα»αααΆααααααααααΆαα Nginx ααΆαααααΆαα’αααΈααΆαα’αα»ααααΆα Kubernetes αααααα»αααα»α Hashicorp ααΎααΆαααααΎα αααΆααααα»αααΈ ClickHouse αααααααΆαααΆαα’αα»ααααΆααα ClickHouse ααΆαα½αααΉαααΆαα’αα»ααααΆαααΆααα ααα’αααΈ? ααΆαααΆαααααααΆααααααααααααααααααα·ααΈαα·ααΆααααΌαααΆαα½ααααΆαααΈααααααααΆα Nginx
ααααα: www.habr.com