НулСв прСстой ΠΏΡ€ΠΈ внСдряванС ΠΈ Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ

НулСв прСстой ΠΏΡ€ΠΈ внСдряванС ΠΈ Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ

Π’Π°Π·ΠΈ статия обяснява ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ ΠΊΠ°ΠΊ Π΄Π° Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ със ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚Ρ‚Π° Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ ΠΏΡ€ΠΈ внСдряванС. Π©Π΅ Π²ΠΈ ΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊΠ²ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС случи с Π²Π°ΡˆΠΈΡ‚Π΅ производствСни прилоТСния, Π°ΠΊΠΎ сС ΠΎΠΏΠΈΡ‚Π°Ρ‚Π΅ Π΄Π° Π²Π½Π΅Π΄Ρ€ΠΈΡ‚Π΅ Π±Π΅Π· ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½Π° ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ°. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Ρ‰Π΅ ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ΠΌ ΠΏΡ€Π΅Π· Π΅Ρ‚Π°ΠΏΠΈΡ‚Π΅ Π½Π° ТизнСния Ρ†ΠΈΠΊΡŠΠ» Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ, ΠΊΠΎΠΈΡ‚ΠΎ са Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ, Π·Π° Π΄Π° ΠΈΠΌΠ° Π½ΡƒΠ»Π΅Π² прСстой (ΠΏΡ€ΠΈΠ±Π». Π»Π΅Π½Ρ‚Π°: ΠΏΠΎ-Π½Π°Ρ‚Π°Ρ‚ΡŠΠΊ - Π½ΡƒΠ»Π΅Π² прСстой). Π Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΡŠΡ‚ ΠΎΡ‚ Π½Π°ΡˆΠΈΡ‚Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Ρ‰Π΅ бъдС ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π½Π΅ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠ°Ρ‚Π° промяна Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ ΠΏΠΎ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌ Π½Π°Ρ‡ΠΈΠ½.

Ако искатС Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Π·Π° ΠΊΠΎΠ΄ ΠΎΡ‚ статията, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π³ΠΈ Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Π½Π° GitHub.

въвСдСниС

Π Π°Π·Π³Ρ€ΡŠΡ‰Π°Π½Π΅ с Π½ΡƒΠ»Π΅Π²ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° прСстой

Каква мистика Ρ€Π°Π·Π³Ρ€ΡŠΡ‰Π°Π½Π΅ с Π½ΡƒΠ»Π΅Π²ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° прСстой? ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΊΠ°ΠΆΠ΅Ρ‚Π΅, Ρ‡Π΅ Ρ‚ΠΎΠ²Π° Π΅, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π²Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΅ Ρ€Π°Π·Π³ΡŠΡ€Π½Π°Ρ‚ΠΎ ΠΏΠΎ Ρ‚Π°ΠΊΡŠΠ² Π½Π°Ρ‡ΠΈΠ½, Ρ‡Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π΄Π° Π²ΡŠΠ²Π΅Π΄Π΅Ρ‚Π΅ Π½ΠΎΠ²Π° вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π² производството, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ потрСбитСлят Π½Π΅ забСлязва липсата ΠΌΡƒ. ΠžΡ‚ Π³Π»Π΅Π΄Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° потрСбитСля ΠΈ компанията, Ρ‚ΠΎΠ²Π° Π΅ Π½Π°ΠΉ-добрият възмоТСн сцСнарий Π·Π° внСдряванС, Π·Π°Ρ‰ΠΎΡ‚ΠΎ позволява Π²ΡŠΠ²Π΅ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π½ΠΎΠ²ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ ΠΊΠΎΡ€ΠΈΠ³ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ Π±Π΅Π· ΠΏΡ€Π΅ΠΊΡŠΡΠ²Π°Π½Π΅.

Как Π΄Π° постигнСм Ρ‚ΠΎΠ²Π°? Има няколко Π½Π°Ρ‡ΠΈΠ½Π°, Π΅Ρ‚ΠΎ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ тях:

  • Π²Π½Π΅Π΄Ρ€ΠΈΡ‚Π΅ вСрсия β„–1 Π½Π° Π²Π°ΡˆΠ°Ρ‚Π° услуга
  • ΠΈΠ·Π²ΡŠΡ€ΡˆΠ΅Ρ‚Π΅ миграция Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ
  • Π Π°Π·ΠΏΠΎΠ»ΠΎΠΆΠ΅Ρ‚Π΅ вСрсия #2 Π½Π° Π²Π°ΡˆΠ°Ρ‚Π° услуга успорСдно с вСрсия #1
  • Π²Π΅Π΄Π½Π°Π³Π° Ρ‰ΠΎΠΌ Π²ΠΈΠ΄ΠΈΡ‚Π΅, Ρ‡Π΅ вСрсия β„– 2 Ρ€Π°Π±ΠΎΡ‚ΠΈ ΠΊΠ°ΠΊΡ‚ΠΎ трябва, ΠΏΡ€Π΅ΠΌΠ°Ρ…Π½Π΅Ρ‚Π΅ вСрсия β„– 1
  • Π³ΠΎΡ‚ΠΎΠ²!

ЛСсно, Π½Π°Π»ΠΈ? Π—Π° съТалСниС Π½Π΅ Π΅ Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° просто ΠΈ Ρ‰Π΅ Π³ΠΎ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠΎ-ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ ΠΏΠΎ-късно. Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ Π΄Ρ€ΡƒΠ³ доста чСсто срСщан процСс Π½Π° внСдряванС - синьо-Π·Π΅Π»Π΅Π½ΠΎ внСдряванС.

Π§ΡƒΠ²Π°Π»ΠΈ Π»ΠΈ стС някога синьо Π·Π΅Π»Π΅Π½ΠΎ Ρ€Π°Π·ΠΏΠΎΠ»Π°Π³Π°Π½Π΅? Cloud Foundry ΠΏΡ€Π°Π²ΠΈ Ρ‚ΠΎΠ²Π° ΠΈΠ·ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ лСсно. ΠŸΡ€ΠΎΡΡ‚ΠΎ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅Ρ‚Π΅ Ρ‚Π°Π·ΠΈ статия, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ описвамС Ρ‚ΠΎΠ²Π° ΠΏΠΎ-ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ. Π—Π° Π΄Π° ΠΎΠ±ΠΎΠ±Ρ‰ΠΈΠΌ Π½Π°ΠΊΡ€Π°Ρ‚ΠΊΠΎ, Π½Π΅ΠΊΠ° Π²ΠΈ Π½Π°ΠΏΠΎΠΌΠ½ΠΈΠΌ ΠΊΠ°ΠΊ Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ синьо-Π·Π΅Π»Π΅Π½ΠΎ внСдряванС:

  • ΡƒΠ²Π΅Ρ€Π΅Ρ‚Π΅ сС, Ρ‡Π΅ Π΄Π²Π΅ копия Π½Π° вашия производствСн ΠΊΠΎΠ΄ (β€žΡΠΈΠ½ΡŒΠΎβ€œ ΠΈ β€žΠ·Π΅Π»Π΅Π½ΠΎβ€œ) работят;
  • насочи цСлия Ρ‚Ρ€Π°Ρ„ΠΈΠΊ към синята срСда, Ρ‚.Π΅. Ρ‚Π°ΠΊΠ° Ρ‡Π΅ производствСнитС URL адрСси Π΄Π° сочат Ρ‚Π°ΠΌ;
  • Π²Π½Π΅Π΄Ρ€ΠΈΡ‚Π΅ ΠΈ тСствайтС всички ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π² Π·Π΅Π»Π΅Π½Π° срСда;
  • ΠΏΡ€Π΅Π²ΠΊΠ»ΡŽΡ‡Π΅Ρ‚Π΅ URL адрСситС ΠΎΡ‚ синя към Π·Π΅Π»Π΅Π½Π° срСда

Биньо-Π·Π΅Π»Π΅Π½ΠΎΡ‚ΠΎ внСдряванС Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, ΠΊΠΎΠΉΡ‚ΠΎ Π²ΠΈ позволява лСсно Π΄Π° Π²ΡŠΠ²Π΅ΠΆΠ΄Π°Ρ‚Π΅ Π½ΠΎΠ²ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π±Π΅Π· Π΄Π° сС притСсняватС ΠΎΡ‚ ΠΏΡ€Π΅ΠΊΡŠΡΠ²Π°Π½Π΅ Π½Π° производството. Π’ΠΎΠ²Π° сС дълТи Π½Π° Ρ„Π°ΠΊΡ‚Π°, Ρ‡Π΅ Π΄ΠΎΡ€ΠΈ Π°ΠΊΠΎ Π½Π΅Ρ‰ΠΎ сС случи, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ лСсно Π΄Π° сС Π²ΡŠΡ€Π½Π΅Ρ‚Π΅ към ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½Π°Ρ‚Π° срСда, ΠΊΠ°Ρ‚ΠΎ просто β€žΠ½Π°Ρ‚ΠΈΡΠ½Π΅Ρ‚Π΅ ΠΏΡ€Π΅Π²ΠΊΠ»ΡŽΡ‡Π²Π°Ρ‚Π΅Π»β€œ.

Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅Ρ‚Π΅ всичко ΠΏΠΎ-Π³ΠΎΡ€Π΅, ΠΌΠΎΠΆΠ΅ Π΄Π° Π·Π°Π΄Π°Π΄Π΅Ρ‚Π΅ Π²ΡŠΠΏΡ€ΠΎΡΠ°: Какво ΠΎΠ±Ρ‰ΠΎ ΠΈΠΌΠ° нулСвият прСстой със синьо-Π·Π΅Π»Π΅Π½ΠΎΡ‚ΠΎ внСдряванС?

Π•, Ρ‚Π΅ ΠΈΠΌΠ°Ρ‚ доста ΠΎΠ±Ρ‰ΠΈ Π½Π΅Ρ‰Π°, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Π½Π΅Ρ‚ΠΎ Π½Π° Π΄Π²Π΅ копия Π½Π° Π΅Π΄Π½Π° ΠΈ ΡΡŠΡ‰Π° срСда изисква Π΄Π²ΠΎΠΉΠ½ΠΎ усилиС Π·Π° ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Π½Π΅Ρ‚ΠΎ ΠΈΠΌ. Π•Ρ‚ΠΎ Π·Π°Ρ‰ΠΎ някои ΠΎΡ‚Π±ΠΎΡ€ΠΈ Ρ‚Π²ΡŠΡ€Π΄ΡΡ‚ ΠœΠ°Ρ€Ρ‚ΠΈΠ½ Π€Π°ΡƒΠ»ΡŠΡ€, слСдвайтС Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π½Π° Ρ‚ΠΎΠ·ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄:

Π”Ρ€ΡƒΠ³ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ Π΅Π΄Π½Π° ΠΈ ΡΡŠΡ‰Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ, създавайки синьо-Π·Π΅Π»Π΅Π½ΠΈ ΠΏΡ€Π΅Π²ΠΊΠ»ΡŽΡ‡Π²Π°Ρ‚Π΅Π»ΠΈ Π·Π° ΡƒΠ΅Π± ΠΈ Π΄ΠΎΠΌΠ΅ΠΉΠ½ слоСвС. ΠŸΡ€ΠΈ Ρ‚ΠΎΠ·ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ чСсто ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, особСно ΠΊΠΎΠ³Π°Ρ‚ΠΎ трябва Π΄Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ Π½Π΅ΠΉΠ½Π°Ρ‚Π° схСма, Π·Π° Π΄Π° ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° Π½ΠΎΠ²Π° вСрсия Π½Π° софтуСра.

И Ρ‚ΡƒΠΊ стигамС Π΄ΠΎ основния ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π² Ρ‚Π°Π·ΠΈ статия. Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ. НСка Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌ ΠΎΡ‚Π½ΠΎΠ²ΠΎ Ρ‚Π°Π·ΠΈ Ρ„Ρ€Π°Π·Π°.

ΠΈΠ·Π²ΡŠΡ€ΡˆΠ΅Ρ‚Π΅ миграция Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ.

Π‘Π΅Π³Π° трябва Π΄Π° си Π·Π°Π΄Π°Π΄Π΅Ρ‚Π΅ Π²ΡŠΠΏΡ€ΠΎΡΠ° - ΠΊΠ°ΠΊΠ²ΠΎ Ρ‰Π΅ станС, Π°ΠΊΠΎ промяната Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π½Π΅ Π΅ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠ°? Няма Π»ΠΈ ΠΏΡŠΡ€Π²Π°Ρ‚Π° ΠΌΠΈ вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π΄Π° сС ΠΏΠΎΠ²Ρ€Π΅Π΄ΠΈ? Π’ΡΡŠΡ‰Π½ΠΎΡΡ‚ Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚ΠΎΠ²Π° Ρ‰Π΅ сС случи...

Π’Π°ΠΊΠ° Ρ‡Π΅, Π΄ΠΎΡ€ΠΈ Π²ΡŠΠΏΡ€Π΅ΠΊΠΈ ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΈΡ‚Π΅ прСдимства Π½Π° нулСвия прСстой/синьо-Π·Π΅Π»Π΅Π½ΠΎ внСдряванС, ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈΡ‚Π΅ са склонни Π΄Π° слСдват слСдния ΠΏΠΎ-бСзопасСн процСс Π·Π° внСдряванС Π½Π° своитС прилоТСния:

  • ΠΏΠΎΠ΄Π³ΠΎΡ‚Π²ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ с Π½ΠΎΠ²Π° вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ
  • Π·Π°Ρ‚Π²ΠΎΡ€Π΅Ρ‚Π΅ Ρ€Π°Π±ΠΎΡ‚Π΅Ρ‰ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
  • стартирайтС скриптовС Π·Π° ΠΌΠΈΠ³Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ
  • внСдряванС ΠΈ стартиранС Π½Π° Π½ΠΎΠ²Π° вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ

Π’ Ρ‚Π°Π·ΠΈ статия Ρ‰Π΅ опишСм ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈΡ‚Π΅ с Π²Π°ΡˆΠ°Ρ‚Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ ΠΈ ΠΊΠΎΠ΄, Π·Π° Π΄Π° сС Π²ΡŠΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΎΡ‚ внСдряванСто Π±Π΅Π· прСстой.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ с Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ

Ако ΠΈΠΌΠ°Ρ‚Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π±Π΅Π· ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅, ΠΊΠΎΠ΅Ρ‚ΠΎ Π½Π΅ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° Π½ΠΈΠΊΠ°ΠΊΠ²ΠΈ Π΄Π°Π½Π½ΠΈ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Π΅Π΄Π½Π°Π³Π° Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π½ΡƒΠ»Π΅Π²ΠΎ внСдряванС Π½Π° прСстой. Π—Π° съТалСниС ΠΏΠΎΠ²Π΅Ρ‡Π΅Ρ‚ΠΎ софтуСри трябва Π΄Π° ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Ρ‚ Π΄Π°Π½Π½ΠΈ някъдС. Π•Ρ‚ΠΎ Π·Π°Ρ‰ΠΎ трябва Π΄Π° помислитС Π΄Π²Π° ΠΏΡŠΡ‚ΠΈ, ΠΏΡ€Π΅Π΄ΠΈ Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ ΠΊΠ°ΠΊΠ²ΠΈΡ‚ΠΎ ΠΈ Π΄Π° Π±ΠΈΠ»ΠΎ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ във Π²Π΅Ρ€ΠΈΠ³Π°Ρ‚Π°. ΠŸΡ€Π΅Π΄ΠΈ Π΄Π° Π½Π°Π²Π»Π΅Π·Π΅ΠΌ Π² подробности Π·Π° Ρ‚ΠΎΠ²Π° ΠΊΠ°ΠΊ Π΄Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ схСмата, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π΄Π° Π΅ възмоТно внСдряванС Π±Π΅Π· прСстой, Π½Π΅ΠΊΠ° ΠΏΡŠΡ€Π²ΠΎ сС ΡΡŠΡΡ€Π΅Π΄ΠΎΡ‚ΠΎΡ‡ΠΈΠΌ Π²ΡŠΡ€Ρ…Ρƒ схСмата Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° вСрсиитС.

Π‘Ρ…Π΅ΠΌΠ° Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° вСрсиитС

Π’ Ρ‚Π°Π·ΠΈ статия Ρ‰Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠŸΡŠΡ‚ Π·Π° ΠΏΡ€Π΅Π»ΠΈΡ‚Π°Π½Π΅ ΠΊΠ°Ρ‚ΠΎ инструмСнт Π·Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ» Π½Π° вСрсиитС (ΠΏΡ€ΠΈΠ±Π». ΠŸΡ€Π΅Π²ΠΎΠ΄: Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π·Π° ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ Π½Π° Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ). ЕстСствСно, Π½ΠΈΠ΅ ΡΡŠΡ‰ΠΎ Ρ‰Π΅ напишСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Spring Boot, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΈΠΌΠ° Π²Π³Ρ€Π°Π΄Π΅Π½Π° ΠΏΠΎΠ΄Π΄Ρ€ΡŠΠΆΠΊΠ° Π½Π° Flyway ΠΈ Ρ‰Π΅ ΠΈΠ·Π²ΡŠΡ€ΡˆΠΈ миграция Π½Π° схСма, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ настройва контСкста Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ. ΠšΠΎΠ³Π°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ Flyway, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Ρ‚Π΅ скриптовС Π·Π° миграция Π² ΠΏΠ°ΠΏΠΊΠ°Ρ‚Π° Π½Π° Π²Π°ΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ (ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ Π² 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 Docs.

ΠšΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ инструмСнт Π·Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ» Π½Π° ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΠΊΠ° с Spring Boot, ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Ρ‚Π΅ 2 Π³ΠΎΠ»Π΅ΠΌΠΈ прСдимства:

  • раздСлятС ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ Π² ΠΊΠΎΠ΄Π°
  • ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΡΡ‚Π° Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° Π·Π°Π΅Π΄Π½ΠΎ с внСдряванСто Π½Π° Π²Π°ΡˆΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Ρ‚.Π΅. Π²Π°ΡˆΠΈΡΡ‚ процСс Π½Π° внСдряванС Π΅ опростСн

ΠžΡ‚ΡΡ‚Ρ€Π°Π½ΡΠ²Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ с Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ

Π’ слСдващия Ρ€Π°Π·Π΄Π΅Π» Π½Π° статията Ρ‰Π΅ сС ΡΡŠΡΡ€Π΅Π΄ΠΎΡ‚ΠΎΡ‡ΠΈΠΌ Π²ΡŠΡ€Ρ…Ρƒ Ρ€Π°Π·Π³Π»Π΅ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π΄Π²Π° ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° към ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ.

  • ΠΎΠ±Ρ€Π°Ρ‚Π½Π° Π½Π΅ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚
  • ΠΎΠ±Ρ€Π°Ρ‚Π½Π° ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚

ΠŸΡŠΡ€Π²ΠΈΡΡ‚ Ρ‰Π΅ сС счита Π·Π° ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅, Ρ‡Π΅ Π½Π΅ трябва Π΄Π° ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°Ρ‚Π΅ внСдряванС с Π½ΡƒΠ»Π΅Π² прСстой Π±Π΅Π· ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½Π° ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ°... Вторият ΠΏΡ€Π΅Π΄Π»Π°Π³Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π·Π° Ρ‚ΠΎΠ²Π° ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΈΠ·Π²ΡŠΡ€ΡˆΠΈΡ‚Π΅ внСдряванС Π±Π΅Π· прСстой ΠΈ Π² ΡΡŠΡ‰ΠΎΡ‚ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π΄Π° ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Ρ‚Π΅ ΠΎΠ±Ρ€Π°Ρ‚Π½Π° ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚.

ΠΠ°ΡˆΠΈΡΡ‚ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, Π²ΡŠΡ€Ρ…Ρƒ ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌ, Ρ‰Π΅ бъдС просто ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Spring Boot Flyway, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΈΠΌΠ° Person с first_name ΠΈ last_name Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ (ΠΏΡ€ΠΈΠ±Π». ΠΏΡ€Π΅Π²ΠΎΠ΄: Person Π΅ маса ΠΈ first_name ΠΈ last_name - Ρ‚ΠΎΠ²Π° са Π½ΠΈΠ²ΠΈΡ‚Π΅ Π² Π½Π΅Π³ΠΎ). ИскамС Π΄Π° ΠΏΡ€Π΅ΠΈΠΌΠ΅Π½ΡƒΠ²Π°ΠΌΠ΅ last_name Π² surname.

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΡ

ΠŸΡ€Π΅Π΄ΠΈ Π΄Π° Π½Π°Π²Π»Π΅Π·Π΅ΠΌ Π² подробноститС, ΠΈΠΌΠ° няколко прСдполоТСния, ΠΊΠΎΠΈΡ‚ΠΎ трябва Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ относно Π½Π°ΡˆΠΈΡ‚Π΅ прилоТСния. ΠžΡΠ½ΠΎΠ²Π½ΠΈΡΡ‚ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚, ΠΊΠΎΠΉΡ‚ΠΎ искамС Π΄Π° постигнСм, Ρ‰Π΅ бъдС доста прост процСс.

Π‘Π΅Π»Π΅ΠΆΠΊΠ°Ρ‚Π°. БизнСс ПРО-Π‘ΠͺΠ’Π•Π’. ΠžΠΏΡ€ΠΎΡΡ‚ΡΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° процСситС ΠΌΠΎΠΆΠ΅ Π΄Π° Π²ΠΈ спСсти ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€ΠΈ Π·Π° ΠΏΠΎΠ΄Π΄Ρ€ΡŠΠΆΠΊΠ° (ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ ΠΏΠΎΠ²Π΅Ρ‡Π΅ Ρ…ΠΎΡ€Π° работят Π·Π° Π²Π°ΡˆΠ°Ρ‚Π° компания, Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΏΠ°Ρ€ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° спСститС)!

Няма Π½ΡƒΠΆΠ΄Π° ΠΎΡ‚ Π²Ρ€ΡŠΡ‰Π°Π½Π΅ Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ

Π’ΠΎΠ²Π° опростява процСса Π½Π° внСдряванС (някои Π²Ρ€ΡŠΡ‰Π°Π½ΠΈΡ Π½Π°Π·Π°Π΄ към Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ са ΠΏΠΎΡ‡Ρ‚ΠΈ нСвъзмоТни, ΠΊΠ°Ρ‚ΠΎ Π²Ρ€ΡŠΡ‰Π°Π½Π΅ към ΠΈΠ·Ρ‚Ρ€ΠΈΠ²Π°Π½Π΅). ΠŸΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°ΠΌΠ΅ Π΄Π° Π²Ρ€ΡŠΡ‰Π°ΠΌΠ΅ само прилоТСния. По Ρ‚ΠΎΠ·ΠΈ Π½Π°Ρ‡ΠΈΠ½, Π΄ΠΎΡ€ΠΈ Π°ΠΊΠΎ ΠΈΠΌΠ°Ρ‚Π΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ SQL ΠΈ NoSQL), Π²Π°ΡˆΠΈΡΡ‚ ΠΊΠ°Π½Π°Π» Π·Π° внСдряванС Ρ‰Π΅ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠΎ ΡΡŠΡ‰ΠΈΡ Π½Π°Ρ‡ΠΈΠ½.

Π’Π˜ΠΠΠ“Π˜ трябва Π΄Π° Π΅ възмоТно ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π΄Π° сС Π²ΡŠΡ€Π½Π΅ Π΅Π΄Π½Π° вСрсия Π½Π°Π·Π°Π΄ (Π½Π΅ ΠΏΠΎΠ²Π΅Ρ‡Π΅)

Π’Ρ€ΡŠΡ‰Π°Π½Π΅ Π½Π°Π·Π°Π΄ трябва Π΄Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° само ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ. Ако ΠΈΠΌΠ° Π³Ρ€Π΅ΡˆΠΊΠ° Π² Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° вСрсия, която Π½Π΅ сС ΠΊΠΎΡ€ΠΈΠ³ΠΈΡ€Π° лСсно, трябва Π΄Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° сС Π²ΡŠΡ€Π½Π΅ΠΌ към Π½Π°ΠΉ-Π½ΠΎΠ²Π°Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚Π΅Ρ‰Π° вСрсия. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΠΌΠ΅, Ρ‡Π΅ Ρ‚Π°Π·ΠΈ послСдна Ρ€Π°Π±ΠΎΡ‚Π½Π° вСрсия Π΅ ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½Π°Ρ‚Π°. ΠŸΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Π½Π΅Ρ‚ΠΎ Π½Π° ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ Π½Π° ΠΊΠΎΠ΄ ΠΈ Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ Π·Π° ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ Π΅Π΄Π½ΠΎ внСдряванС Π±ΠΈ Π±ΠΈΠ»ΠΎ ΠΈΠ·ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ ΠΈ скъпо.

Π‘Π΅Π»Π΅ΠΆΠΊΠ°Ρ‚Π°. Π—Π° ΠΏΠΎ-голяма чСтливост Π² Ρ‚Π°Π·ΠΈ статия Ρ‰Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΠΌ основната вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ.

Π‘Ρ‚ΡŠΠΏΠΊΠ° 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.

ΡΡ‚ΡŠΠΏΠΊΠΈ:

  1. Π΅ Π²Π½Π΅Π΄Ρ€Π΅Π½ Π½ΠΎΠ² СкзСмпляр Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π·Π° вСрсия 2.0.0.BADΠΊΠΎΠΉΡ‚ΠΎ Π°ΠΊΡ‚ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π΄ΠΎ v2bad
  2. Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ v2bad ΠΊΠΎΠ»ΠΎΠ½Π° last_name Π²Π΅Ρ‡Π΅ Π½Π΅ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π° - бСшС ΠΏΡ€ΠΎΠΌΠ΅Π½Π΅Π½ΠΎ Π½Π° surname
  3. Актуализацията Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ бСшС ΡƒΡΠΏΠ΅ΡˆΠ½Π° ΠΈ някои копия сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚ 1.0.0, Π΄Ρ€ΡƒΠ³ΠΈ - Π² 2.0.0.BAD. Всичко Π΅ ΡΠ²ΡŠΡ€Π·Π°Π½ΠΎ с Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ v2bad
  4. всички СкзСмпляри Π½Π° вСрсията 1.0.0 Ρ‰Π΅ Π·Π°ΠΏΠΎΡ‡Π½Π°Ρ‚ Π΄Π° ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Ρ‚ Π³Ρ€Π΅ΡˆΠΊΠΈ, Π·Π°Ρ‰ΠΎΡ‚ΠΎ Ρ‰Π΅ сС ΠΎΠΏΠΈΡ‚Π°Ρ‚ Π΄Π° Π²ΠΌΡŠΠΊΠ½Π°Ρ‚ Π΄Π°Π½Π½ΠΈ Π² ΠΊΠΎΠ»ΠΎΠ½Π°Ρ‚Π° last_nameΠΊΠΎΠΉΡ‚ΠΎ Π²Π΅Ρ‡Π΅ Π½Π΅ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°
  5. всички СкзСмпляри Π½Π° вСрсията 2.0.0.BAD Ρ‰Π΅ Ρ€Π°Π±ΠΎΡ‚ΠΈ Π±Π΅Π· ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ

ΠšΠ°ΠΊΡ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅, Π°ΠΊΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π½Π΅ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ, A/B тСстванСто Π΅ нСвъзмоТно.

Π’Ρ€ΡŠΡ‰Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ

Π”Π° ΠΏΡ€ΠΈΠ΅ΠΌΠ΅ΠΌ, Ρ‡Π΅ слСд ΠΊΠ°Ρ‚ΠΎ сС ΠΎΠΏΠΈΡ‚Π°Ρ‚Π΅ Π΄Π° ΠΈΠ·Π²ΡŠΡ€ΡˆΠΈΡ‚Π΅ A/B внСдряванС (ΠΏΡ€ΠΈΠ±Π». per.: Ρ‚ΡƒΠΊ Π°Π²Ρ‚ΠΎΡ€ΡŠΡ‚ вСроятно Π΅ ΠΈΠΌΠ°Π» ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ A/B тСстванС) Ρ€Π΅ΡˆΠΈΡ…ΠΌΠ΅, Ρ‡Π΅ трябва Π΄Π° Π²ΡŠΡ€Π½Π΅ΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π΄ΠΎ вСрсията 1.0.0. Π”Π° ΠΊΠ°ΠΆΠ΅ΠΌ, Ρ‡Π΅ Π½Π΅ искамС Π΄Π° Π²ΡŠΡ€Π½Π΅ΠΌ Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ.

ΡΡ‚ΡŠΠΏΠΊΠΈ:

  1. спирамС СкзСмпляра Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π·Π° вСрсия 2.0.0.BAD
  2. Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π΅ всС ΠΎΡ‰Π΅ v2bad
  3. Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ вСрсията 1.0.0 Π½Π΅ Ρ€Π°Π·Π±ΠΈΡ€Π° ΠΊΠ°ΠΊΠ²ΠΎ Π΅ surname, Ρ‰Π΅ Π²ΠΈΠ΄ΠΈΠΌ Π³Ρ€Π΅ΡˆΠΊΠΈ
  4. Π°Π΄ΡŠΡ‚ ΠΈΠ·Π±ΡƒΡ…Π½Π°, Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° сС Π²ΡŠΡ€Π½Π΅ΠΌ ΠΏΠΎΠ²Π΅Ρ‡Π΅

ΠšΠ°ΠΊΡ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅, Π°ΠΊΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π½Π΅ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ, Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° сС Π²ΡŠΡ€Π½Π΅ΠΌ към ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½Π°Ρ‚Π° вСрсия.

Π–ΡƒΡ€Π½Π°Π»ΠΈ Π·Π° изпълнСниС Π½Π° скриптовС

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, Ρ‚ΠΎΠΉ няма Π΄Π° сС ΠΏΠΎΠ²Ρ€Π΅Π΄ΠΈ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° изпълнСниС.

ΠŸΡƒΡΠΊΠ°ΠΌΠ΅ Π½ΠΎΠ²Π° вСрсия

ΡΡ‚ΡŠΠΏΠΊΠΈ:

  1. ΠΈΠ·Π²ΡŠΡ€ΡˆΠ΅Ρ‚Π΅ миграция Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ, Π·Π° Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ Π½ΠΎΠ²Π° ΠΊΠΎΠ»ΠΎΠ½Π° surname. Π‘Π΅Π³Π° Π²Π°ΡˆΠ°Ρ‚Π° DB вСрсия v2
  2. ΠΊΠΎΠΏΠΈΡ€Π°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ last_name Π² surname. Моля, ΠΎΠ±ΡŠΡ€Π½Π΅Ρ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅Ρ‡Π΅ Π°ΠΊΠΎ ΠΈΠΌΠ°Ρ‚Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΡ‚ Ρ‚Π΅Π·ΠΈ Π΄Π°Π½Π½ΠΈ, трябва Π΄Π° помислитС Π·Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π½Π° миграция!
  3. Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΊΠΎΠ΄Π°, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ И Π”Π’Π•Π’Π• ΠΈ новИ старата ΠΊΠΎΠ»ΠΎΠ½Π°. Π‘Π΅Π³Π° Π²Π°ΡˆΠ°Ρ‚Π° вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ 2.0.0
  4. ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅Ρ‚Π΅ стойността ΠΎΡ‚ ΠΊΠΎΠ»ΠΎΠ½Π°Ρ‚Π° surname, Π°ΠΊΠΎ Π½Π΅ Π΅ null, ΠΈΠ»ΠΈ ΠΎΡ‚ Π»ast_name, Π°ΠΊΠΎ surname Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΎ. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΈΠ·Ρ‚Ρ€ΠΈΠ΅Ρ‚Π΅ getLastName() ΠΎΡ‚ ΠΊΠΎΠ΄Π°, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Ρ‰Π΅ ΠΈΠ·Π²Π΅Π΄Π΅ null ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π²Ρ€ΡŠΡ‰Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ си ΠΎΡ‚ 3.0.0 Π΄ΠΎ 2.0.0.

Ако ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ Spring Boot Flyway, Ρ‚Π΅Π·ΠΈ Π΄Π²Π΅ ΡΡ‚ΡŠΠΏΠΊΠΈ Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ изпълнСни ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° стартиранС Π½Π° вСрсията 2.0.0 прилоТСния. Ако стартиратС инструмСнта Π·Π° вСрсия Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Ρ€ΡŠΡ‡Π½ΠΎ, Ρ‰Π΅ трябва Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ Π΄Π²Π΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Π½Π΅Ρ‰Π°, Π·Π° Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ Ρ‚ΠΎΠ²Π° (ΠΏΡŠΡ€Π²ΠΎ Π°ΠΊΡ‚ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€Π°ΠΉΡ‚Π΅ Ρ€ΡŠΡ‡Π½ΠΎ вСрсията Π½Π° db ΠΈ слСд Ρ‚ΠΎΠ²Π° Π²Π½Π΅Π΄Ρ€ΠΈΡ‚Π΅ Π½ΠΎΠ²ΠΎΡ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅).

Π’ΠΎΠ²Π° Π΅ Π²Π°ΠΆΠ½ΠΎ. НС забравяйтС, Ρ‡Π΅ Π½ΠΎΠ²ΠΎΡΡŠΠ·Π΄Π°Π΄Π΅Π½Π°Ρ‚Π° ΠΊΠΎΠ»ΠΎΠ½Π° НЕ ВРЯБВА бъдС НЕ Π• ΠΠ£Π›ΠΠž. Ако Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ Π²Ρ€ΡŠΡ‰Π°Π½Π΅ Π½Π°Π·Π°Π΄, старото ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ Π·Π½Π°Π΅ Π·Π° Π½ΠΎΠ²Π°Ρ‚Π° ΠΊΠΎΠ»ΠΎΠ½Π° ΠΈ няма Π΄Π° Π³ΠΎ инсталира ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Insert. Но Π°ΠΊΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚Π΅ Ρ‚ΠΎΠ²Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ ΠΈ Π²Π°ΡˆΠΈΡΡ‚ db Ρ‰Π΅ бъдС v2, Ρ‚ΠΎΠ²Π° Ρ‰Π΅ изисква Π·Π°Π΄Π°Π²Π°Π½Π΅ Π½Π° стойността Π½Π° Π½ΠΎΠ²Π°Ρ‚Π° ΠΊΠΎΠ»ΠΎΠ½Π°. ΠšΠΎΠ΅Ρ‚ΠΎ Ρ‰Π΅ Π΄ΠΎΠ²Π΅Π΄Π΅ Π΄ΠΎ Π½Π°Ρ€ΡƒΡˆΠ°Π²Π°Π½Π΅ Π½Π° ограничСнията.

Π’ΠΎΠ²Π° Π΅ Π²Π°ΠΆΠ½ΠΎ. Врябва Π΄Π° ΠΏΡ€Π΅ΠΌΠ°Ρ…Π½Π΅Ρ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° getLastName(), Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ във вСрсията 3.0.0 Π’ ΠΊΠΎΠ΄Π° няма концСпция Π·Π° ΠΊΠΎΠ»ΠΎΠ½Π° last_name. Π’ΠΎΠ²Π° ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ Ρ‚Π°ΠΌ Ρ‰Π΅ бъдС Π·Π°Π΄Π°Π΄Π΅Π½Π° Π½ΡƒΠ»Π°. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° оставитС ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π·Π° null, Π½ΠΎ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π±ΠΈ Π±ΠΈΠ»ΠΎ Π΄Π° сС ΡƒΠ²Π΅Ρ€ΠΈΡ‚Π΅, Ρ‡Π΅ Π² Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° getSurname() стС ΠΈΠ·Π±Ρ€Π°Π»ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π½Π°Ρ‚Π° Π½Π΅Π½ΡƒΠ»Π΅Π²Π° стойност.

A/B тСстванС

Π’Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° ситуация Π΅, Ρ‡Π΅ ΠΈΠΌΠ°ΠΌΠ΅ вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ 1.0.0, Ρ€Π°Π·Π³ΡŠΡ€Π½Π°Ρ‚ΠΈ Π² производството ΠΈ Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π² v1. Врябва Π΄Π° Π²Π½Π΅Π΄Ρ€ΠΈΠΌ Π²Ρ‚ΠΎΡ€ΠΎ ΠΊΠΎΠΏΠΈΠ΅ Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π·Π° вСрсия 2.0.0ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ Π°ΠΊΡ‚ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π΄ΠΎ v2.

ΡΡ‚ΡŠΠΏΠΊΠΈ:

  1. Π΅ Π²Π½Π΅Π΄Ρ€Π΅Π½ Π½ΠΎΠ² СкзСмпляр Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π·Π° вСрсия 2.0.0ΠΊΠΎΠΉΡ‚ΠΎ Π°ΠΊΡ‚ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π΄ΠΎ v2
  2. ΠΌΠ΅ΠΆΠ΄ΡƒΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ някои заявки бяха ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π΅Π½ΠΈ ΠΎΡ‚ СкзСмпляри Π½Π° вСрсия 1.0.0
  3. актуализацията бСшС ΡƒΡΠΏΠ΅ΡˆΠ½Π° ΠΈ ΠΈΠΌΠ°Ρ‚Π΅ мноТСство Ρ€Π°Π±ΠΎΡ‚Π΅Ρ‰ΠΈ СкзСмпляри Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π·Π° вСрсия 1.0.0 ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ вСрсии 2.0.0. ВсСки ΠΊΠΎΠΌΡƒΠ½ΠΈΠΊΠΈΡ€Π° с Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π² v2
  4. вСрсия 1.0.0 Π½Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΊΠΎΠ»ΠΎΠ½Π°Ρ‚Π° Π·Π° фамилия Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ, Π° вСрсията 2.0.0 ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°. Π’Π΅ Π½Π΅ си ΠΏΡ€Π΅Ρ‡Π°Ρ‚ ΠΈ Π½Π΅ трябва Π΄Π° ΠΈΠΌΠ° Π³Ρ€Π΅ΡˆΠΊΠΈ.
  5. вСрсия 2.0.0 ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° Π΄Π°Π½Π½ΠΈ ΠΊΠ°ΠΊΡ‚ΠΎ Π² старата, Ρ‚Π°ΠΊΠ° ΠΈ Π² Π½ΠΎΠ²Π°Ρ‚Π° ΠΊΠΎΠ»ΠΎΠ½Π°, осигурявайки ΠΎΠ±Ρ€Π°Ρ‚Π½Π° ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚

Π’ΠΎΠ²Π° Π΅ Π²Π°ΠΆΠ½ΠΎ. Ако ΠΈΠΌΠ°Ρ‚Π΅ някакви заявки, ΠΊΠΎΠΈΡ‚ΠΎ броят Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈ въз основа Π½Π° стойности ΠΎΡ‚ старата/Π½ΠΎΠ²Π°Ρ‚Π° ΠΊΠΎΠ»ΠΎΠ½Π°, трябва Π΄Π° Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Π΅ сСга ΠΈΠΌΠ°Ρ‚Π΅ Π΄ΡƒΠ±Π»ΠΈΡ€Π°Ρ‰ΠΈ сС стойности (Π½Π°ΠΉ-вСроятно Ρ‚Π΅ всС ΠΎΡ‰Π΅ ΠΌΠΈΠ³Ρ€ΠΈΡ€Π°Ρ‚). НапримСр, Π°ΠΊΠΎ искатС Π΄Π° ΠΏΡ€Π΅Π±Ρ€ΠΎΠΈΡ‚Π΅ броя Π½Π° ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΠΈΡ‚Π΅, Ρ‡ΠΈΠ΅Ρ‚ΠΎ Ρ„Π°ΠΌΠΈΠ»Π½ΠΎ ΠΈΠΌΠ΅ (ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ Π΄Π° сС Π½Π°Ρ€ΠΈΡ‡Π° ΠΊΠΎΠ»ΠΎΠ½Π°Ρ‚Π°) Π·Π°ΠΏΠΎΡ‡Π²Π° с Π±ΡƒΠΊΠ²Π°Ρ‚Π° A, слСд ΠΊΠΎΠ΅Ρ‚ΠΎ Π΄ΠΎΠΊΠ°Ρ‚ΠΎ миграцията Π½Π° Π΄Π°Π½Π½ΠΈΡ‚Π΅ ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡ΠΈ (old β†’ new ΠΊΠΎΠ»ΠΎΠ½Π°) ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ°Ρ‚Π΅ нСпослСдоватСлни Π΄Π°Π½Π½ΠΈ, Π°ΠΊΠΎ заявитС Π½ΠΎΠ²Π° ΠΊΠΎΠ»ΠΎΠ½Π°.

Π’Ρ€ΡŠΡ‰Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ

Π‘Π΅Π³Π° ΠΈΠΌΠ°ΠΌΠ΅ вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ 2.0.0 ΠΈ Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ Π² v2.

ΡΡ‚ΡŠΠΏΠΊΠΈ:

  1. Π²ΡŠΡ€Π½Π΅Ρ‚Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ си Π΄ΠΎ вСрсия 1.0.0.
  2. вСрсия 1.0.0 Π½Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΊΠΎΠ»ΠΎΠ½Π° Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ surname, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π²Ρ€ΡŠΡ‰Π°Π½Π΅Ρ‚ΠΎ Π½Π°Π·Π°Π΄ трябва Π΄Π° Π΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ

ΠŸΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² Π‘Π”

Π‘Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° ΠΊΠΎΠ»ΠΎΠ½Π° с ΠΈΠΌΠ΅ 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.

Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅. НС забравяйтС, Ρ‡Π΅ НЕ ΠœΠžΠ–Π•Π’Π• ДА Π”ΠžΠ‘ΠΠ’Π―Π’Π• Π½ΠΈΠΊΠ°ΠΊΠ²ΠΈ NOT 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: ΠŸΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅ Π½Π° last_name ΠΎΡ‚ ΠΊΠΎΠ΄Π°

ВСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ: 3.0.0

DB вСрсия:v3

ΠšΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€

Π—Π°Π±Π΅Π»Π΅ΠΆΠΊΠ° per.: ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ Π² ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½Π°Ρ‚Π° статия Π°Π²Ρ‚ΠΎΡ€ΡŠΡ‚ ΠΏΠΎΠ³Ρ€Π΅ΡˆΠΊΠ° Π΅ ΠΊΠΎΠΏΠΈΡ€Π°Π» тСкста Π½Π° Ρ‚ΠΎΠ·ΠΈ Π±Π»ΠΎΠΊ ΠΎΡ‚ ΡΡ‚ΡŠΠΏΠΊΠ° 2. На Ρ‚Π°Π·ΠΈ ΡΡ‚ΡŠΠΏΠΊΠ° трябва Π΄Π° сС направят ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² ΠΊΠΎΠ΄Π° Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ, насочСни към ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅ Π½Π° функционалността, която ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΊΠΎΠ»ΠΎΠ½Π°Ρ‚Π° last_name.

Π§Ρ€Π΅Π· добавянС Π½Π° Π½ΠΎΠ²Π° ΠΊΠΎΠ»ΠΎΠ½Π° ΠΈ ΠΊΠΎΠΏΠΈΡ€Π°Π½Π΅ Π½Π° Π½Π΅ΠΉΠ½ΠΎΡ‚ΠΎ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅ ΡΡŠΠ·Π΄Π°Π΄ΠΎΡ…ΠΌΠ΅ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ. Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ°, Π°ΠΊΠΎ Π²ΡŠΡ€Π½Π΅ΠΌ JAR Π½Π°Π·Π°Π΄ ΠΈΠ»ΠΈ стартирамС стар JAR, Ρ‚ΠΎΠΉ няма Π΄Π° сС ΠΏΠΎΠ²Ρ€Π΅Π΄ΠΈ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° изпълнСниС.

Π’Ρ€ΡŠΡ‰Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ

Π’ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° ΠΈΠΌΠ°ΠΌΠ΅ вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ 3.0.0 ΠΈ Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ v3. ВСрсия 3.0.0 Π½Π΅ записва Π΄Π°Π½Π½ΠΈ Π² last_name. Π’ΠΎΠ²Π° ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ Π² surname сС ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° Π½Π°ΠΉ-Π°ΠΊΡ‚ΡƒΠ°Π»Π½Π°Ρ‚Π° информация.

ΡΡ‚ΡŠΠΏΠΊΠΈ:

  1. Π²ΡŠΡ€Π½Π΅Ρ‚Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ си Π΄ΠΎ вСрсия 2.0.0.
  2. вСрсия 2.0.0 ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΈ last_name ΠΈ surname.
  3. вСрсия 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;

ΠŸΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² ΠΊΠΎΠ΄Π°

Π—Π°Π±Π΅Π»Π΅ΠΆΠΊΠ° ΠΏΠ΅Ρ€.: ΠžΠΏΠΈΡΠ°Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Ρ‚ΠΎΠ·ΠΈ Π±Π»ΠΎΠΊ ΡΡŠΡ‰ΠΎ бСшС ΠΏΠΎΠ³Ρ€Π΅ΡˆΠ½ΠΎ ΠΊΠΎΠΏΠΈΡ€Π°Π½ΠΎ ΠΎΡ‚ Π°Π²Ρ‚ΠΎΡ€Π° ΠΎΡ‚ ΡΡ‚ΡŠΠΏΠΊΠ° 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: ΠŸΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅ Π½Π° last_name ΠΎΡ‚ Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ

ВСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ: 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"}

ΠŸΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² Π‘Π”

Π—Π° 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. внСдряванС Π½Π° вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ 1.0.0 с v1 схСма Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ (ΠΈΠΌΠ΅ Π½Π° ΠΊΠΎΠ»ΠΎΠ½Π° = last_name)
  2. внСдряванС Π½Π° вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ 2.0.0, ΠΊΠΎΠΉΡ‚ΠΎ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° Π΄Π°Π½Π½ΠΈ Π² last_name ΠΈ surname. ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Ρ‡Π΅Ρ‚Π΅ ΠΎΡ‚ last_name. Π‘Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π΅ във вСрсия v2ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‰ΠΈ ΠΊΠΎΠ»ΠΎΠ½ΠΈ ΠΊΠ°Ρ‚ΠΎ last_nameИ surname. surname Π΅ ΠΊΠΎΠΏΠΈΠ΅ Π½Π° Π»ast_name. (Π—ΠΠ‘Π•Π›Π•Π–ΠšΠ: Π’Π°Π·ΠΈ ΠΊΠΎΠ»ΠΎΠ½Π° Π½Π΅ трябва Π΄Π° ΠΈΠΌΠ° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ Π½Π΅ Π½ΡƒΠ»Π°)
  3. внСдряванС Π½Π° вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ 3.0.0, ΠΊΠΎΠΉΡ‚ΠΎ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° Π΄Π°Π½Π½ΠΈ само Π² surname ΠΈ сС Ρ‡Π΅Ρ‚Π΅ ΠΎΡ‚ фамилията. Π©ΠΎ сС отнася Π΄ΠΎ Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ, послСдната миграция сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° last_name Π² surname. Π‘ΡŠΡ‰ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ НЕ Π• ΠΠ£Π›ΠΠž ΠΏΡ€Π΅ΠΌΠ°Ρ…Π½Π°Ρ‚ ΠΎΡ‚ last_name. Π‘Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π²Π΅Ρ‡Π΅ Π΅ във вСрсия v3
  4. внСдряванС Π½Π° вСрсия Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ 4.0.0 - Π½Π΅ сС правят ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² ΠΊΠΎΠ΄Π°. Π Π°Π·Π³Ρ€ΡŠΡ‰Π°Π½Π΅ Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ v4, ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π° last_name. Π’ΡƒΠΊ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡ‚Π΅ всички липсващи ограничСния към Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ.

ΠšΠ°Ρ‚ΠΎ слСдватС Ρ‚ΠΎΠ·ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, Π²ΠΈΠ½Π°Π³ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΡŠΡ€Π½Π΅Ρ‚Π΅ Π΅Π΄Π½Π° вСрсия Π½Π°Π·Π°Π΄, Π±Π΅Π· Π΄Π° Π½Π°Ρ€ΡƒΡˆΠ°Π²Π°Ρ‚Π΅ ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚Ρ‚Π° Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ/ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.

Код

ЦСлият ΠΊΠΎΠ΄, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ Π² Ρ‚Π°Π·ΠΈ статия, Π΅ Π΄ΠΎΡΡ‚ΡŠΠΏΠ΅Π½ Π½Π° Github. По-Π΄ΠΎΠ»Ρƒ ΠΈΠΌΠ° Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΎ описаниС.

ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ

Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ ΠΊΠ»ΠΎΠ½ΠΈΡ€Π°Ρ‚Π΅ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅Ρ‚ΠΎ, Ρ‰Π΅ Π²ΠΈΠ΄ΠΈΡ‚Π΅ слСдната структура Π½Π° ΠΏΠ°ΠΏΠΊΠΈΡ‚Π΅.

β”œβ”€β”€ 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

ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° стартиратС скриптовСтС, описани Π² скриптовСтС ΠΏΠΎ-Π΄ΠΎΠ»Ρƒ, ΠΊΠΎΠΈΡ‚ΠΎ Ρ‰Π΅ дСмонстрират ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΈ ΠΈ Π½Π΅ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ.

Π—Π° Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ случаят с ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ, стартирайтС:

./scripts/scenario_backward_compatible.sh

И Π΄Π° видя случай с ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π½Π΅ΡΡŠΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ, стартирайтС:

./scripts/scenario_backward_incompatible.sh

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Π΅Π½ Flyway Π·Π° ΠΏΡ€ΠΎΠ»Π΅Ρ‚Π½ΠΎ Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅

Всички ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ са Π²Π·Π΅Ρ‚ΠΈ ΠΎΡ‚ Spring Boot Sample Flyway.

ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°Ρ‚Π΅ http://localhost:8080/flyway, ΠΈΠΌΠ° списък със скриптовС.

Π’ΠΎΠ·ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π²ΠΊΠ»ΡŽΡ‡Π²Π° ΠΈ ΠΊΠΎΠ½Π·ΠΎΠ»Π°Ρ‚Π° H2 (Π² http://localhost:8080/h2-console), Ρ‚Π°ΠΊΠ° Ρ‡Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ (URL Π°Π΄Ρ€Π΅ΡΡŠΡ‚ ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ Π½Π° jdbc Π΅ jdbc:h2:mem:testdb).

ОсвСн Ρ‚ΠΎΠ²Π°

ΠŸΡ€ΠΎΡ‡Π΅Ρ‚Π΅Ρ‚Π΅ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ статии Π² нашия Π±Π»ΠΎΠ³:

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€