
Selles artiklis käsitletakse, kuidas lahendada andmebaaside ühilduvusprobleeme juurutamise ajal. Räägime, mis võib juhtuda teie rakendustega tootmises, kui proovite juurutada ilma eelneva ettevalmistuseta. Seejärel vaatame rakenduse elutsükli etappe, mis on vajalikud null aegete saavutamiseks (märkus: edaspidi — nulla aega). Meie tegevuse tulemuseks on tagasi pöörduva mitteühilduva muudatuse rakendamine tagasi ühilduval viisil.
Kui soovite artiklist koodi näiteid, leiate need aadressilt .
Sissejuhatus
Nulla aega jaandmine
Mis see müstiline nulla aega jaandmine? Можно сказать, это когда ваше приложение развернуто так, что вы можете успешно вводить новую версию приложения на продакшн, в то время как пользователь не замечает его недоступности. С точки зрения пользователя и компании, это наилучший из возможных сценариев деплоя, поскольку таким образом можно вводить новые функции и устранять ошибки без перебоев в работе.
Kuidas seda saavutada? On mitmeid viise, siin on üks neist:
- juurutage teenuse versioon №1
- tehke andmebaasi migreerimine
- juurutage teenuse versioon №2 paralleelselt versiooniga №1
- kui näete, et versioon №2 töötab nagu peab, eemaldage versioon №1
- valmis!
Lihtne, eks? Kahjuks ei ole see nii lihtne, ja me arutame seda hiljem üksikasjalikult. Kuid praegu vaadakem veel ühte üsna levinud deploy protsessi — blue green deployment.
Oled sa kunagi kuulnud ? С Cloud Foundry это чрезвычайно легко сделать. Просто гляньте на , kus me käsitleme seda põhjalikumalt. Kokkuvõtlikult tuletame meelde, kuidas teha blue green deployment:
- tagada, et kaks koopiat sinu production koodist (“blue” ja “green”) töötaksid;
- suunata kogu liiklus blue keskkonda, st et tootmisse aadressid osutaksid sinna;
- deploida ja testida kõik rakenduse muudatused green keskkonnas;
- vahetada URL- aadressid blue keskkonnast green keskkonda.
Blue green deployment on lähenemine, mis võimaldab sul lihtsalt uusi funktsioone sisse tuua, muretsemata, et tootmine katki läheb. See on seotud sellega, et isegi kui midagi juhtub, saad lihtsalt "lülitiga klõpsates" tagasi eelnevasse keskkonda.
Kuna oled kõik eelneva läbi lugenud, võid küsida: Millist seost zero downtime'il on blue green deploy'ga?
Noh, neil on üsna palju ühist, kuna kahe sama keskkonna koopia toetamine nõuab kahekordseid pingutusi nende hooldamiseks. Seetõttu väidab mõned meeskonnad, , järgides selle lähenemise variatsioone:
teine variant on kasutada sama andmebaasi, luues sinised-rohelised vahetused veebikliendi ja domeenikihtide vahel. Sellise lähenemise puhul võivad andmebaasid tihti probleemiks saada, eriti kui peate muutma nende skeemi uue tarkvaraversiooni toetamiseks.
Ja siin me jõuame selle artikli peamise probleemini. Andmebaas. Vaadakem sellele lausele veel kord.
tehke andmebaasi migratsioon.
Nüüd peaksite endalt küsima – mis siis, kui andmebaasi muutmine on tagasivõetamatu? Kas minu esialgne rakenduse versioon ei purune? Tegelikult juhtub just see...
Seega, vaatamata zero downtime / blue green deployment tohututele eelistele, kalduvad ettevõtted järgima järgmist, turvalisemat rakenduste juurutamise protsessi:
- valmistada ette uus rakenduse versioon
- keelata jooksva rakenduse
- käivitada andmebaasi migratsiooni skriptid
- juurutada ja käivitada uus rakenduse versioon
Selles artiklis käsitleme üksikasjalikult, kuidas saate andmebaasi ja koodi kasutada, et teha kasutusele zero downtime deployment.
Andmebaasiprobleemid
Kui teil on stateless rakendus, mis ei salvesta andmeid andmebaasis, saate zero downtime deploymenti kohe. Kahjuks peab suurem osa tarkvarast salvestama andmeid kusagil. Just sel põhjusel peaksite enne schéma muudatuste tegemist kaks korda mõtlema. Enne kui jõuame selliste muudatuste detailideni, mis võimaldavad downtime'iga juurutamise, keskendume esiteks versioonihalduse skeemile.
Versioonihalduse skeem
Selles artiklis kasutame versioonihaldustööriistana (märkus tõlkijalt: jutt on andmebaasi migreerimistest). Loomulikult kirjutame ka Spring Boot rakenduse, millel on sisseehitatud Flyway tugi ja mis viib schéma migreerimise läbi rakenduse konteksti seadistamise ajal. Flyway kasutamisel saate salvestada migreerimisk skriptid oma projektide kaustas (vaikimisi classpath:db/migration). Siin näete näidet sellistest migreerimisfailidest.
└── db
└── migration
├── V1__init.sql
├── V2__Add_surname.sql
├── V3__Final_migration.sql
└── V4__Remove_lastname.sqlSelles näites näeme 4 migreerimisskeemi, mis, kui nad pole varem rakendatud, täidetakse rakenduse käivitamisel järjestikku. Vaatame üht failidest (V1__init.sql) näiteks.
Loo tabel PERSON (
id BIGINT GENEREERITUD VAID AINULT IDENTITEEDI KUNA,
first_name varchar(255) mitte null,
last_name varchar(255) mitte null
);
sisesta INTO PERSON (first_name, last_name) VALUES ('Dave', 'Syer');Kõik räägib enda eest: saate kasutada SQL-i, et määrata, kuidas teie andmebaas peaks muutuma. Täiendava teabe saamiseks Spring Booti ja Flyway kohta tutvuge .
Kasutades versioonihaldustööriista koos Spring Bootiga, saate 2 suurt eelist:
- te eraldate andmebaasi muudatused koodimuudatustest
- andmebaasi migratsioon toimub koos teie rakenduse juurutamisega, st teie juurutamisprotsess lihtsustub
Andmebaasi probleemide lahendamine
Artikli järgmises osas keskendume kahte lähenemisviisi andmebaasi muudatuste arutamisele.
- tagasiühilduvus
- tagasiühilduvus
Esimene hoiatab, et null-seisakuga juurutust ei tohiks teha ilma eelneva ettevalmistuseta... Teine pakub lahendust, kuidas juurutada seisakuteta ja samal ajal säilitada tagurpidi ühilduvus.
Meie projekt, millega hakkame tegelema, on lihtne Spring Boot Flyway rakendus, milles on Isik koos eesnimi ja perekonnanimi andmebaasis (märkus: Isik on tabel ning feesnimi ja perekonnanimi on selle väljad). Soovime ümber nimetada perekonnanimi ühes perekonnanimi.
Eeldused
Enne kui süveneme detailidesse, on oluline märkida paar eeldust meie rakenduste kohta. Peamine tulemus, mida soovime saavutada, on üsna lihtne protsess.
Märkus. Ärisoovitus. Protsesside lihtsustamine võib säästa teile palju raha halduskuludelt (mida rohkem inimesi teie ettevõttes töötab, seda rohkem raha saate säästa)!
Andmebaasi tagasiviimist ei tohiks teha.
See lihtsustab juurutamisprotsessi (mõned andmebaasi tagasiviimised on praktiliselt võimatud, näiteks kustutamise tagasiviimine). Eelistame tagasiviimist ainult rakendustele. Nii on teie juurutamise toru ühtne, isegi kui teil on erinevad andmebaasid (nt SQL ja NoSQL).
Rakendust tuleb alati võimalikult tagasi viia ühte versiooni (mitte rohkem).
Tagasiviimist tuleb teha ainult vajadusel. Kui praeguses versioonis on viga, mida on raske parandada, peame saama tagasi viia viimase töötava versiooni. Eeldame, et see viimane töötav versioon on eelmine. Koodi ja andmebaasi ühilduvuse säilitamine enam kui ühe väljalaskega oleks äärmiselt keeruline ja kulukas.
Märkus. Suurema loetavuse huvides muudame käesolevas artiklis rakenduse suurversiooni.
Samm 1: Algseisund
Rakenduse versioon: 1.0.0
Andmebaasi versioon: v1
Kommentaar
See on rakenduse algseisund.
Andmebaasi muudatused
Andmebaas sisaldab 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');Koodi muutmine
Rakendus salvestab andmed isiku kohta perekonnanimi:
/*
* 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
+ "]";
}
}Tagasiühilduv veeru ümbernimetamine
Vaatame näidet, kuidas muuta veeru nime:
Tähelepanu. Järgmine näide põhjustab tahtlikult rikke. Me näitame seda, et demonstreerida andmebaasi ühilduvuse probleemi.
Rakenduse versioon: 2.0.0.BAD
DB versioon: v2bad
Kommentaar
Praegused muudatused EI luba meil käivitada kahte eksemplari (vana ja uus) samaaegselt. Seega, nullist katkestamata juurutamine on raske saavutada (kui arvestada eeldusi, on see tegelikult võimatu).
A/B testimine
Praegune olukord on selline, et meil on versiooni rakendus 1.0.0, toodetud, ja andmebaas v1. Peame juurutama teise rakenduse eksemplari, versiooni 2.0.0.BAD, ja värskendama andmebaasi kuni v2bad.
Sammud:
- toodud uus rakenduse eksemplar versioon
2.0.0.BAD, which updates the database tov2bad - andmebaasis
v2badveergperekonnanimiei eksisteeri enam — see on muudetudperekonnanimi - andmebaasi ja rakenduse värskendamine õnnestus, ning mõned eksemplarid töötavad
1.0.0, teised —2.0.0.BAD. Kõik on seotud andmebaasigav2bad - kõik versiooni eksemplarid
1.0.0hakkavad andma vigu, sest nad proovivad sisestada andmeid veerguperekonnanimi, mida enam ei ole - kõik versiooni eksemplarid
2.0.0.BADtöötavad tõrgeteta
Nagu näete, kui teeme tagasipoole ühilduvaid muudatusi andmebaasis ja rakenduses, pole A/B testimine võimalik.
Rakenduse tagasipöördumine
Oletame, et pärast A/B juurutuse katset (märk. tõlk.: tõenäoliselt mõtles autor A/B testimist) otsustasime, et peame rakenduse tagasi versioonile pöörduma 1.0.0. Oletame, et me ei soovi andmebaasi tagasipöörata.
Sammud:
- peatame rakenduse eksemplari versioonis
2.0.0.BAD - andmebaas on endiselt
v2bad - kuna versioon
1.0.0ei saa aru, mis onperekonnanimi, näeme vigu - paha, mis pääses vabadusse, me ei saa enam tagasi pöörduda
Nagu näete, kui teeme tagasipoole ühilduvaid muudatusi andmebaasis ja rakenduses, ei saa me naasta varasema versiooni juurde.
Skripti täitmise logid
Tagasiühilduv stsenaarium:
01) Käivita versioon 1.0.0
02) Oota, kuni rakendus (1.0.0) käivitub
03) Loo inimene, tehes POST localhost:9991/person versioonile 1.0.0
04) Käivita 2.0.0.BAD
05) Oota, kuni rakendus (2.0.0.BAD) käivitub
06) Loo inimene, tehes POST localhost:9991/person versioonile 1.0.0 <-- see peaks ebaõnnestuma
07) Loo inimene, tehes POST localhost:9992/person versioonile 2.0.0.BAD <-- see peaks õnnestuma
Käivitamine rakenduses versioonis 1.0.0
Inimese loomine versioonis 1.0.0
POST 127.0.0.1:9991/person saatmine. See on vastus:
{"firstName":"b73f639f-e176-4463-bf26-1135aace2f57","lastName":"b73f639f-e176-4463-bf26-1135aace2f57"}
Käivitamine rakenduses versioonis 2.0.0.BAD
Inimese loomine versioonis 1.0.0
POST 127.0.0.1:9991/person saatmine. See on vastus:
curl: (22) Taotletud URL tagastas vea: 500 Internal Server Error
Inimese loomine versioonis 2.0.0.BAD
POST 127.0.0.1:9995/person saatmine. See on vastus:
{"firstName":"e156be2e-06b6-4730-9c43-6e14cfcda125","surname":"e156be2e-06b6-4730-9c43-6e14cfcda125"}Andmebaasi muudatused
Migreerimisskript, mis ümber nimetab perekonnanimi ühes perekonnanimi
Algne Flyway skript:
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');Skript, mis ümber nimetab perekonnanimi.
-- See muudatus on tagasiviidav - A/B testimist ei saa teha
ALTER TABLE PERSON CHANGE last_name surname VARCHAR;Koodi muutmine
Me muutsime välja nime lastName järgnevaga perekonnanimi.
Veeru ümber nimetamine tagasiviidaval viisil
See on kõige levinum olukord, millega me kokku puutume. Me peame tegema tagasipöördumatud muutused. Oleme juba tõestanud, et katkestusteta juurutamiseks ei tohi me lihtsalt andmebaasi migreerimist rakendada ilma täiendavate toiminguteta. Artikli selles osas teeme kolm rakenduse juurutamist koos andmebaasi migreerimisega, et saavutada soovitud tulemus ja samal ajal säilitada tagasipöördumatuse ühilduvus.
Märkus. Kordame, et meil on andmebaasi versioon
v1. See sisaldab veergeeesnimijaperekonnanimi. Me peame muutmaperekonnanimijärgnevagaperekonnanimi. Samuti on meil rakendus versiooniga1.0.0,mis ei kasuta veelperekonnanimi.
Samm 2: Lisame perekonnanime
Rakenduse versioon: 2.0.0
Andmebaasi versioon: v2
Kommentaar
Uue veeru lisamisel ja selle sisu kopeerimisel loome tagasipöördumatult ühilduvad andmebaasi muudatused. Samal ajal, kui me tagastame JAR-i või kui meil on töötav vana JAR, ei tohiks see töötamise ajal katki minna.
Juhtige uut versiooni
Sammud:
- sooritage andmebaasi migreerimine, et luua uus veerg
perekonnanimi. Nüüd on teie andmebaasi versioonv2 - koopiate andmed
perekonnanimiühesperekonnanimi. Pange tähele, et kui teil on palju neid andmeid, peaksite kaaluma grupimigratsiooni! - kirjutage kood, kus kasutatakse KOHAL ja uus, ja vana veeru. Nüüd on teie rakenduse versioon
2.0.0 - loe väärtus veerust
perekonnanimi, kui see ei olenull, või last_name, kuiperekonnanimiei ole määratud. Saate eemaldadagetLastName()koodist, kuna see toob esilenullrakenduse tagasivõtmisel3.0.0kuni2.0.0.
Kui kasutate Spring Boot Flyway, siis need kaks sammu tehakse versiooni käivitamise ajal 2.0.0 rakendus. Kui te käivitate andmebaasi versioonihaldustööriista käsitsi, peate tegema kaks eraldi toimingut (esiteks uuendage andmebaasi versioon käsitsi ja seejärel juurutage uus rakendus).
Oluline. Pidage meeles, et uus veerg EI TOHI olla NOT NULL. Kui teete tagasivõtu, siis vana rakendus ei tea uuest veerust ja ei seadista seda ajal
Sisestamine.Aga kui te lisate selle piirmäära, ja teie andmebaas onv2, siis see nõuab uue veeru väärtuse seadmist. Mis viib piirangute riknemiseni.Oluline. Peaksite eemaldama meetodi
getLastName(), kuna versioonis3.0.0koodis ei ole veeru mõistetperekonnanimi. See tähendab, et seal seadistatakse null. Saate meetodi jätta ja lisada kontrollidnull, kuid palju parem lahendus oleks tagada, etgetSurname()olete valinud õige mitte-null väärtuse.
A/B testimine
Praegune olukord on selline, et meil on versiooni rakendus 1.0.0, juurutatud tootmises, ja andmebaas olevat v1. Me peame juurutama teise versiooni rakenduse koopia 2.0.0, mis uuendab andmebaasi versioonini v2.
Sammud:
- toodud uus rakenduse eksemplar versioon
2.0.0, which updates the database tov2 - samal ajal mõned päringud töötasid versiooni eksemplaridega
1.0.0 - uuendus läks edukalt ja teil on mitu töötavat rakenduse versiooni
1.0.0ja ülejäänud versioonid2.0.0.K kõik suhtlevad andmebaasigav2 - versioon
1.0.0ei kasuta andmebaasis veergu surname, samas kui versioon2.0.0kasutab. Nad ei sega üksteist ja vigu ei tohiks olla. - versioon
2.0.0salvestab andmeid nii vanas kui uues veerus, mis tagab tagasiühilduvuse
Oluline. Kui teil on mingeid päringuid, mis loendavad elemente vanade/uute veergude väärtuste põhjal, peate meeles pidama, et nüüd on teil väärtuste dubleerimine (tõenäoliselt nad veel migratsioonis). Näiteks kui soovite lugeda kasutajate arvu, kelle perekonnanimi (sõltumata veeru nimest) algab tähega
A, siis andmete migratsiooni lõpuni (vana→uusveeru) võivad teil olla ebaühtlased andmed, kui teete päringu uude veergu.
Rakenduse tagasipöördumine
Praegu on meil rakendus versioon 2.0.0 ja andmebaas v2.
Sammud:
- veerake oma rakendus versioonini
1.0.0. - versioon
1.0.0ei kasuta andmebaasis veerguperekonnanimi, seetõttu peab tagasivõtmine olema edukas
Andmebaasi muudatused
Andmebaas sisaldab veergu nimega perekonnanimi.
Algne Flyway skript:
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');Lisamisskript perekonnanimi.
Tähelepanu. Pange tähele, et ei tohi lisada ühtegi NOT NULL piirangut lisatavasse veergu. Kui te tagasivõtmise JAR-i, siis vana versioon ei tea lisatud veerust midagi ja seadistab selle automaatselt NULL-iks. Kui selline piirang on olemas, puruneb vana rakendus lihtsalt.
-- MÄRKUS: Sellel väljadel ei saa olla NOT NULL piirangut, sest kui te tagasi võtate, ei tea vana versioon sellest väljast
-- ja seadistab selle alati NULL-iks
ALTER TABLE PERSON ADD surname varchar(255);
-- ESMALT OLEME ARVANUD, ET SEE ON KIIRE MIGREERIMINE - MUUD JUHUL PEAME MIGREERIMA PARTIIDENA
UPDATE PERSON SET PERSON.surname = PERSON.last_nameKoodi muutmine
Salvestame andmed nii perekonnanimi, kui ka perekonnanimi. Samal ajal loeme perekonnanimi, kuna see veerg on kõige asjakohasem. Deployimise käigus võidi mõned päringud töödelda rakenduse instantsiga, mis ei olnud veel uuendatud.
/*
* 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
+ "]";
}
}Samm 3: last_name eemaldamine sümbolist
Rakenduse versioon: 3.0.0
DB versioon:v3
Kommentaar
Toimetaja märkus: Ilmselt on algses artiklis autor selle bloki teksti ekslikult kopeerinud sammust 2. Sel sammul tuleb teha muudatusi rakenduse koodis, mis on suunatud funktsionaalsuse eemaldamisele, mis kasutab veergu perekonnanimi.
Uue veeru lisamise ja selle sisu kopeerimisega oleme loonud andmebaasi tagasilühilduvad muudatused. Samuti, kui me naaseme vanemasse JAR-faili või meil on töötav vana JAR, siis see ei purune käitamise ajal.
Rakenduse tagasipöördumine
Meil on hetkel versiooni 3.0.0 ja andmebaas v3. Versioon 3.0.0 ei salvesta andmeid perekonnanimi. See tähendab, et perekonnanimi hoiab kõige ajakohasemat teavet.
Sammud:
- veerake oma rakendus versioonini
2.0.0. - versioon
2.0.0kasutab japerekonnanimijaperekonnanimi. - versioon
2.0.0võtabperekonnanimi, kui see ei ole null, muidu —perekonnanimi
Andmebaasi muudatused
Andmebaasis pole struktuurimuudatusi. Käitatakse järgmist skripti, mis teostab vanade andmete lõpliku migratsiooni:
-- ELEGIME KIIRE MIGRATSIOONI - KUI EI, PEAME MIGREERIMA PARTIIDENA
-- KA EI KONTROLLI ME, KAS ME EI KATTA OLEMASOLEVAID KANNE. PEAME VÕRDLEMA
-- KANNE VERSIOONE, ET VEENDUDA, KAS OLEMAS OLEVAT KANNE KÕRGEMA VERSIOONI NUMBRIGA
-- ME EI KATA SEDA.
UPDATE PERSON SET PERSON.surname = PERSON.last_name;
-- KUSTUTAME MITTE NULL KOHUSTUSE; MU otherwise PROOVITE SISSE KANDA NULL VÄÄRTUSE LAST_NAME
-- MITTE_NULL KOHUSTUSEGA.
ALTER TABLE PERSON MODIFY COLUMN last_name varchar(255) NULL DEFAULT NULL;Koodi muutmine
Märkus: Selle ploki kirjeldus on autori poolt ekslikult kopeeritud sammust 2. Artikli narratiivi loogika kohaselt peaks selle sammu koodimuudatus suunama eemaldama elemente, mis töötavad veeru kallal. perekonnanimi.
Me salvestame andmeid nii perekonnanimi, kui ka perekonnanimi. Lisaks loeme veerust perekonnanimi, kuna see on kõige asjakohasem. Juurutamise käigus võivad mõned päringud töötlemiseks kasutada instantsi, mis pole veel värskendatud.
/*
* 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
+ "]";
}
}Samm 4: last_name eemaldamine andmebaasist
Rakenduse versioon: 4.0.0
Andmebaasi versioon: v4
Kommentaar
Kuna versiooni kood 3.0.0 ei kasutanud veergu perekonnanimi, pole täitmise ajal midagi halba, kui me taastume 3.0.0 pärast veeru eemaldamist andmebaasist.
Skripti täitmise logid
Me teeme seda järgmistel viisidel:
01) Käivita 1.0.0
02) Oota, kuni rakendus (1.0.0) käivitub
03) Generaatori loomine helistades POST localhost:9991/person versioonile 1.0.0
04) Käivita 2.0.0
05) Oota, kuni rakendus (2.0.0) käivitub
06) Generaatori loomine helistades POST localhost:9991/person versioonile 1.0.0
07) Generaatori loomine helistades POST localhost:9992/person versioonile 2.0.0
08) Lõpeta rakendus (1.0.0)
09) Käivita 3.0.0
10) Oota, kuni rakendus (3.0.0) käivitub
11) Generaatori loomine helistades POST localhost:9992/person versioonile 2.0.0
12) Generaatori loomine helistades POST localhost:9993/person versioonile 3.0.0
13) Lõpeta rakendus (3.0.0)
14) Käivita 4.0.0
15) Oota, kuni rakendus (4.0.0) käivitub
16) Generaatori loomine helistades POST localhost:9993/person versioonile 3.0.0
17) Generaatori loomine helistades POST localhost:9994/person versioonile 4.0.0
Rakenduse käivitamine versioonis 1.0.0
Generaatori loomine versioonis 1.0.0
Postitamine aadressile 127.0.0.1:9991/person. See on vastus:
{"firstName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2","lastName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2"}
Rakenduse käivitamine versioonis 2.0.0
Generaatori loomine versioonis 1.0.0
Postitamine aadressile 127.0.0.1:9991/person. See on vastus:
{"firstName":"e41ee756-4fa7-4737-b832-e28827a00deb","lastName":"e41ee756-4fa7-4737-b832-e28827a00deb"}
Generaatori loomine versioonis 2.0.0
Postitamine aadressile 127.0.0.1:9992/person. See on vastus:
{"firstName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","lastName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","surname":"0c1240f5-649a-4bc5-8aa9-cff855f3927f"}
Rakenduse lõpetamine 1.0.0
Rakenduse käivitamine versioonis 3.0.0
Generaatori loomine versioonis 2.0.0
Postitamine aadressile 127.0.0.1:9992/person. See on vastus:
{"firstName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","lastName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","surname":"74d84a9e-5f44-43b8-907c-148c6d26a71b"}
Generaatori loomine versioonis 3.0.0
Postitamine aadressile 127.0.0.1:9993/person. See on vastus:
{"firstName":"c6564dbe-9ab5-40ae-9077-8ae6668d5862","surname":"c6564dbe-9ab5-40ae-9077-8ae6668d5862"}
Rakenduse lõpetamine 2.0.0
Rakenduse käivitamine versioonis 4.0.0
Generaatori loomine versioonis 3.0.0
Postitamine aadressile 127.0.0.1:9993/person. See on vastus:
{"firstName":"cbe942fc-832e-45e9-a838-0fae25c10a51","surname":"cbe942fc-832e-45e9-a838-0fae25c10a51"}
Generaatori loomine versioonis 4.0.0
Postitamine aadressile 127.0.0.1:9994/person. See on vastus:
{"firstName":"ff6857ce-9c41-413a-863e-358e2719bf88","surname":"ff6857ce-9c41-413a-863e-358e2719bf88"}Andmed DB muudatused
Seoses v3 kuid me eemaldame lihtsalt veeru perekonnanimi ja lisame puuduvad piirangud.
-- EEMALDA VEERG
ALTER TABLE PERSON DROP last_name;
-- Lisa PIIRANGUD
UPDATE PERSON SET surname='' WHERE surname IS NULL;
ALTER TABLE PERSON ALTER COLUMN surname VARCHAR NOT NULL;Koodi muutmine
Koodimuudatusi ei ole.
Kokkuvõte
Oleme tagasi lükanud ühilduvuse muutuse veeru nime osas, tehes mitu tagasi ühilduvat juurutust. Allpool on kokkuvõte tehtud toimingutest:
- rakenduse versiooni juurutamine
1.0.0koosv1DB skeem (veeru nimi =perekonnanimi) - rakenduse versiooni juurutamine
2.0.0,mis säilitab andmeidperekonnanimijaperekonnanimi. Rakendus loebperekonnanimi. DB on versioonisv2, mis sisaldab veerge naguperekonnanimi, kui kasurname. surnameon l koopiaast_name. (MÄRKUS: sellel veerul ei tohiks olla not null piirangut) - rakenduse versiooni juurutamine
3.0.0, mis säilitab andmeid ainultperekonnanimija loeb surname. Mis puudutab DB-d, toimub viimane migratsioonperekonnanimiühesperekonnanimi. Samuti eemaldatakse piirang NOT NULL veerultperekonnanimi. DB on nüüd versioonisv3 - rakenduse versiooni juurutamine
4.0.0— koodis ei toimu mingeid muudatusi. DB juurutaminev4, mis eemaldabperekonnanimi. Siia saate lisada kõik puuduvad piirangud DB-s.
Selle lähenemise järgimisega saate alati tagasi minna ühe versiooni võrra, rikkuvad DB / rakenduse ühilduvust.
Kood
Kogu selles artiklis kasutatud kood on saadaval . Allpool lisainformatsioon.
Projektid
Pärast hoidla kloonimist näete järgmist kaustastruktuuri.
├── boot-flyway-v1 - 1.0.0 versioon rakendusest koos skeemi v1-ga
├── boot-flyway-v2 - 2.0.0 versioon rakendusest koos skeemi v2-ga (tagasi ühilduv - rakendust saab tagasivõtta)
├── boot-flyway-v2-bad - 2.0.0.BAD versioon rakendusest koos skeemi v2bad-ga (tagasi ühilduv mitte - rakendust ei saa tagasivõtta)
├── boot-flyway-v3 - 3.0.0 versioon rakendusest koos skeemi v3-ga (rakendust saab tagasivõtta)
└── boot-flyway-v4 - 4.0.0 versioon rakendusest koos skeemi v4-ga (rakendust saab tagasivõtta)Skriptid
Saate käivitada allpool kirjeldatud skripte, mis demonstreerivad tagasi ühilduvaid ja mitteühilduvaid muudatusi andmebaasis.
Et näha tagasi ühilduvate muudatuste juhtumit, käivitage:
./scripts/scenario_backward_compatible.shJa et näha tagasi mitteühilduvate muudatuste juhtumit, käivitage:
./scripts/scenario_backward_incompatible.shSpring Boot Näidis Flyway
Kõik näidised on võetud Spring Boot Näidis Flyway.
Saate vaadata http://localhost:8080/flyway, seal on skriptide nimekiri.
See näidis sisaldab ka H2 konsooli (aadressil http://localhost:8080/h2-console), et saaksite vaadata andmebaasi seisukorda (URL jdbc vaikimisi - jdbc:h2:mem:testdb).
Lisaks
Vaata ka teisi artikleid meie blogis:
Allikas: habr.com
