{"id":338474,"date":"2022-09-18T09:00:06","date_gmt":"2022-09-18T09:00:06","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=338474"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=338474","title":{"rendered":"<span>\u041c\u0438\u043b\u043b\u0438\u0430\u0440\u0434 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u043e\u0432 \u041c\u0418\u0420\u042d\u0410 2<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/c8f\/e24\/b33\/c8fe24b3393e6707cdd5567c897990ef.jpeg\" width=\"480\" height=\"380\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c8f\/e24\/b33\/c8fe24b3393e6707cdd5567c897990ef.jpeg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0430\u0432\u0442\u043e\u0440 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u043f\u0440\u0438\u0435\u043c\u043d\u043e\u0439 \u043a\u043e\u043c\u043c\u0438\u0441\u0438\u0438 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043c\u0438\u043b\u043b\u0438\u0430\u0440\u0434\u0430 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u043e\u0432 \u0437\u0430 \u043e\u0434\u0438\u043d \u0434\u0435\u043d\u044c. \u0412 \u044d\u0442\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0430\u0432\u0442\u043e\u0440 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Spring + JDBCTemplate \u0438 Kafka \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b.<\/p>\n<h2>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f<\/h2>\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044e \u0431\u044b\u043b\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0448\u0438\u043d\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0436\u0434\u0443 \u043c\u043e\u0434\u0443\u043b\u044f\u043c\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u0447\u0442\u0435\u043d\u0438\u044f. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0443\u0447\u0435\u0441\u0442\u044c, \u0447\u0442\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0438, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u0440\u043e\u0441\u0442\u0435 \u0447\u0438\u0441\u043b\u0430 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439 \u0432 \u043e\u0434\u0438\u043d \u0442\u043e\u043f\u0438\u043a \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u0430\u044f \u0447\u0438\u0441\u043b\u043e\u043c \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e\u043c\u043d\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u043d\u0430 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u043a \u043c\u043e\u0434\u0443\u043b\u044f\u043c \u0447\u0442\u0435\u043d\u0438\u044f, \u0442\u043e \u043f\u0440\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u043f\u0438\u043a\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 24\/7. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/513\/64d\/db2\/51364ddb2f5912383b4d97c9962e23d0.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1. \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u043f\u0438\u043a\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1. \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u043f\u0438\u043a\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438\" width=\"805\" height=\"204\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/513\/64d\/db2\/51364ddb2f5912383b4d97c9962e23d0.png\"\/><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1. \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u043f\u0438\u043a\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438<\/figcaption><\/figure>\n<p>\u041d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 1 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0438 \u0442\u043e\u043f\u0438\u043a\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 N \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0432 L \u0442\u043e\u043f\u0438\u043a\u043e\u0432, \u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0448\u0438\u043d\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044e N \u043d\u0430 L. \u0427\u0442\u043e \u0431\u044b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0432 \u043e\u0434\u043d\u0443 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044e, \u0442\u0430\u043a \u0436\u0435 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0438 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u043f\u043e\u0437\u0436\u0435. \u0418\u0442\u043e\u0433\u043e, \u0438\u043c\u0435\u044f N*122 \u043c\u0431\/\u0441 &#8212; \u043e\u0431\u044a\u0435\u043c \u043e\u0431\u0449\u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c N*L \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443, \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u0443\u043b\u044c\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0438 \u043e\u0431\u044b\u0447\u043d\u043e \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c\u0438 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0430\u043c\u0438.<\/p>\n<p>\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0432 \u0434\u0430\u043d\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0443 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u0434\u0435\u043d\u044c \u0441\u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430, \u0435\u0441\u043b\u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u043d\u0430 \u043b\u0438\u043d\u0435\u0439\u043d\u043e \u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0430 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u0442\u0430\u043a\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0440\u0430\u0432\u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0435 (\u0447\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0442\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0439 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u044b, \u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u0441\u0440\u0435\u0434\u043d\u0435\u043d\u0438\u044f). \u041f\u043e\u0441\u043b\u0435 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438 \u0431\u0435\u0441\u0441\u043e\u043d\u043d\u044b\u0445 \u043d\u043e\u0447\u0435\u0439 \u0432 \u043f\u043e\u0438\u0441\u043a\u0430\u0445 \u044d\u0442\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430, \u0430\u0432\u0442\u043e\u0440 \u043f\u0440\u0438\u0448\u0435\u043b \u043a \u0432\u044b\u0432\u043e\u0434\u0443, \u0447\u0442\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u043c\u0430 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/d07\/878\/533\/d07878533b9020a72663dc36c7788f1e.jpeg\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2. \u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0441\u0430\u043c\u044b\u0439 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2. \u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0441\u0430\u043c\u044b\u0439 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441\" width=\"997\" height=\"740\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d07\/878\/533\/d07878533b9020a72663dc36c7788f1e.jpeg\" data-blurred=\"true\"\/><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2. \u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0441\u0430\u043c\u044b\u0439 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441<\/figcaption><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u0436\u0435 \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u043e, \u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u0442\u0432\u0430 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0436\u0438\u0437\u043d\u0435\u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0415\u0441\u043b\u0438 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432, \u0441\u0435\u0442\u0435\u0439 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0442\u043e \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u0435\u0434\u0435\u043b (\u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0437\u0430\u043a\u043e\u043d\u0430\u043c \u0444\u0438\u0437\u0438\u043a\u0438, \u0430 \u0442\u043e\u0447\u043d\u0435\u0435 \u0440\u0430\u0434\u0438\u0443\u0441\u0443 \u0428\u0432\u0430\u0440\u0446\u0448\u0438\u043b\u044c\u0434\u0430), \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e-\u0432\u0440\u0435\u043c\u044f \u0441\u0445\u043b\u043e\u043f\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u0438\u043d\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c \u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0441\u0441\u043b\u0435\u0434\u043d\u043e.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043e\u0434\u043d\u0443 \u043e\u0446\u0435\u043d\u043a\u0443 \u0430\u0432\u0442\u043e\u0440 \u0434\u0430\u0442\u044c \u043c\u043e\u0436\u0435\u0442. \u0414\u0430\u043d\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0434\u043e\u043b\u0436\u043d\u043e \u0445\u0432\u0430\u0442\u0438\u0442\u044c \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u0442\u0432\u0443 \u043d\u0430 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0435 \u043f\u0430\u0440\u0443 \u043c\u043b\u043d \u043b\u0435\u0442 +- \u0441\u043e\u0442\u043d\u044e \u0442\u044b\u0441\u044f\u0447\u0435\u043b\u0435\u0442\u0438\u0439. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0434\u043b\u044f \u0432\u0430\u0441 \u0442\u0430\u043a\u043e\u0439 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0438 \u043d\u0435\u043f\u0440\u0438\u0435\u043c\u043b\u0438\u043c\u044b\u0439 &#8212; \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440\u0430\u043c. \u0410\u0432\u0442\u043e\u0440 \u0443\u0432\u0435\u0440\u0435\u043d, \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0434\u043e\u043b\u0433\u043e\u0441\u0440\u043e\u0447\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0427\u0442\u043e \u0431\u044b \u043d\u0435 \u0437\u0430\u0445\u043b\u0430\u043c\u043b\u044f\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438, \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440\u043e\u0432, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432\u0448\u0438\u0445 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435, \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 \u0441\u043f\u043e\u0439\u043b\u0435\u0440\u0435 \u043d\u0438\u0436\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440\u043e\u0432, \u0441\u043f\u0440\u0430\u0432\u0438\u0432\u0448\u0438\u0445\u0441\u044f \u0441 \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0435\u043c<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/1a4\/b2d\/d6b\/1a4b2dd6bd9d3055d6f795b999366106.jpeg\" width=\"660\" height=\"400\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1a4\/b2d\/d6b\/1a4b2dd6bd9d3055d6f795b999366106.jpeg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442 \u0431\u0430\u043d\u0430\u043d!<\/p>\n<h2>\u041c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438<\/h2>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/post\/579058\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u0431\u044b\u043b\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u043e\u0439 \u0411\u0414, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432\u0441\u0435 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b. \u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043c\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0421\u0430\u043c\u0430 \u0411\u0414 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043c\u043e\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. <\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0441\u0442\u0430\u0442\u0435\u0439, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043c\u043e\u0434\u0443\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438. <\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u043f\u0440\u0438\u0435\u043c\u043d\u044b\u0445 \u043a\u0430\u043c\u043f\u0430\u043d\u0438\u0439, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0442\u044c:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE scp_write_service.session (     session_id INT     NOT NULL,     active     BOOLEAN NOT NULL DEFAULT TRUE,     CONSTRAINT session_pk PRIMARY KEY (session_id) ); CREATE TABLE scp_write_service.spec (     spec_id UUID    NOT NULL,     active  BOOLEAN NOT NULL DEFAULT TRUE,     CONSTRAINT spec_pk PRIMARY KEY (spec_id) );<\/code><\/pre>\n<p>\u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0440\u0438\u0435\u043c\u043d\u044b\u0445 \u043a\u0430\u043c\u043f\u0430\u043d\u0438\u0439, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439. \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u044d\u0442\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044e. \u0425\u043e\u0442\u044f \u0434\u043b\u044f \u043f\u0440\u0438\u0435\u043c\u043d\u043e\u0439 \u043a\u0430\u043c\u043f\u0430\u043d\u0438\u0438 \u0444\u043b\u0430\u0433 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0443\u0436\u0435\u043d, \u0442\u043e \u0434\u043b\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 &#8212; \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d, \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u043d\u0430\u0447\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0411\u0414, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u0443\u044e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430. \u042d\u0442\u043e\u0442 \u0444\u043b\u0430\u0433 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043f\u0440\u0438\u0435\u043c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0439, \u043d\u0435 \u043d\u0430\u0440\u0443\u0448\u0430\u044f \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c \u0411\u0414.<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE scp_write_service.enrollee (     user_id          UUID      NOT NULL,     session_id       INT       NOT NULL,     -- if this user should no longer be able to perform any operation     disabled         BOOLEAN   NOT NULL DEFAULT FALSE,     -- selected speciality id     selected_spec_id UUID               DEFAULT NULL,     -- how much application may be sent by this enrollee     selection_count  SMALLINT  NOT NULL DEFAULT 20,     created_stamp    TIMESTAMP NOT NULL DEFAULT current_timestamp,     modified_stamp   TIMESTAMP NOT NULL DEFAULT current_timestamp,     CONSTRAINT enrollee_pk PRIMARY KEY (user_id, session_id),     CONSTRAINT enrollee_session_id_fk FOREIGN KEY (session_id) REFERENCES scp_write_service.session (session_id),     CONSTRAINT enrollee_selected_spec_id_fk FOREIGN KEY (selected_spec_id) REFERENCES scp_write_service.spec (spec_id),     CONSTRAINT enrollee_selection_count_positive_chk CHECK ( selection_count >= 0 ) );<\/code><\/pre>\n<p>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u0430 \u0445\u0440\u0430\u043d\u0438\u0442 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043d\u0435\u043c, \u0430 \u0442\u0430\u043a \u0436\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u044e\u0449\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u0442\u043e\u043a\u0435\u043d\u043e\u043c (\u0441\u0432\u043e\u0435\u0433\u043e \u0440\u043e\u0434\u0430). \u0422\u0430\u043a\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0443\u0447\u0430\u0441\u0442\u0438\u0435 \u0432 \u043f\u0440\u0438\u0435\u043c\u043d\u043e\u0439 \u043a\u0430\u043c\u043f\u0430\u043d\u0438\u0438 \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b. \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u043e\u0434\u0443\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u0435\u043b\u044f\u0442 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0442\u043e \u0434\u0430\u043d\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0442\u0438 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e.<\/p>\n<p>\u041f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 enrollee, \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u0432\u0435\u0434\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u043d\u0430\u043c \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0443\u0434\u0430\u0440\u0438\u0442\u0441\u044f \u0432 \u0441\u0445\u0435\u043c\u043e\u0442\u043e\u0437 \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u044b\u0435 \u0441\u0443\u043c\u043c\u044b \u0438\u043b\u0438 \u0435\u0449\u0435 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0431\u0435\u0437\u0443\u043c\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0436\u0435\u0447\u044c \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u044d\u043d\u0435\u0440\u0433\u0438\u044e \u0432 \u0441\u0442\u0438\u043b\u0435 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u043e\u0432, \u043e\u0434\u043d\u0430\u043a\u043e \u0430\u0432\u0442\u043e\u0440 \u0432\u044b\u0431\u0440\u0430\u043b \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442.<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE scp_write_service.enrollee_select (     user_id         UUID      NOT NULL,     session_id      INT       NOT NULL,     spec_id         UUID      NOT NULL,     -- current selection status, 0 for applied, 1 for confirmed and 2 for cancelled     status          SMALLINT  NOT NULL DEFAULT 0,     -- the assigned user score     score           INT       NOT NULL DEFAULT 0,     -- stamp for creation(application) date     created_stamp   TIMESTAMP NOT NULL DEFAULT current_timestamp,     -- stamp for confirmation date     confirmed_stamp TIMESTAMP          DEFAULT NULL,     -- stamp for cancelled date     canceled_stamp  TIMESTAMP          DEFAULT NULL,      ---------------------------------------     --     integrity check fields        --     ---------------------------------------     -- each time modification occurs, this stamp should be updated     modified_stamp  TIMESTAMP NOT NULL DEFAULT current_timestamp,     -- should be treated like 'version', this way we will make     -- possible to reduce amount of response messages sent by target module     -- otherwise we'll deal with lots of duplicates     ordinal         SMALLINT           DEFAULT 0,     -- current integrity check state, 0 - not sent, 1 - sent but not confirmed, 2 - sent and confirmed     state           SMALLINT  NOT NULL DEFAULT 0,      CONSTRAINT enrollee_select_pk PRIMARY KEY (user_id, session_id, spec_id),     CONSTRAINT enrollee_select_user_fk FOREIGN KEY (user_id, session_id) REFERENCES scp_write_service.enrollee (user_id, session_id),     CONSTRAINT enrollee_select_spec_fk FOREIGN KEY (spec_id) REFERENCES scp_write_service.spec (spec_id) );<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 (\u0430 \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0432 \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u043e\u0434\u0443\u043b\u044c \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b enrollee_select), \u043f\u043e\u043b\u0435 state \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 1, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430, \u043d\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0435\u0449\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e. \u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043b\u0435 ordinal \u0440\u0430\u0432\u043d\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u0436\u0435 \u043f\u043e\u043b\u044e \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 state \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 2, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u0431\u044b\u043b\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043e \u043f\u0440\u0438\u0435\u043c\u0435 \u043c\u043e\u0434\u0443\u043b\u0435\u043c \u0447\u0442\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u0443\u0437\u043d\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u0441\u0442\u0430\u0442\u0443\u0441.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435, \u0442\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0435 state \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 0, \u0447\u0442\u043e \u0431\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0435\u0449\u0435 \u0440\u0430\u0437. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u0440\u0430\u0437\u0443 \u0432\u043e \u0432\u0441\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0434\u043d\u043e\u0439. \u0427\u0442\u043e \u0431\u044b \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"pgsql\">UPDATE scp_write_service.enrollee_select SET    state = 0,    ordinal = ordinal + 1, -- we must change ordinal, otherwise read                          -- module won't send confirmation again   modified_stamp = CURRENT_TIMESTAMP WHERE state = 1    AND modified_stamp &lt; timezone('utc', now())::date - interval '1 hours'<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043d\u044f\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437 \u0432 15 \u043c\u0438\u043d\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u044d\u0442\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0411\u0414. \u0413\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e \u0431\u044b \u0435\u0433\u043e \u0437\u0432\u0430\u043b\u0438 \u041a\u0440\u043e\u043d\u043e\u0441 \u0438\u043b\u0438 \u0443 \u043d\u0435\u0433\u043e \u0431\u044b\u043b\u0430 \u043a\u0440\u043e\u043d-\u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0444\u0430\u043c\u0438\u043b\u0438\u044f, \u0438\u043d\u0430\u0447\u0435 \u043d\u0435 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>\u0414\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0411\u0414 \u0437\u0430\u0432\u0435\u0434\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043e\u043d\u0438 \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443.<\/p>\n<pre><code class=\"pgsql\">CREATE FUNCTION scp_write_service.select_insert()     RETURNS trigger AS $select_insert$ BEGIN     -- do not allow invalid parameters to be passed     -- confirmation or cancelling must be performed by UPDATE statement     -- rather than insert     IF NEW.status &lt;> 0 THEN         RAISE EXCEPTION 'Invalid status value : %', NEW.status             USING HINT = 'status = 0';     END IF;     UPDATE scp_write_service.enrollee e     SET selection_count = selection_count - 1,         modified_stamp  = current_timestamp     WHERE e.user_id = NEW.user_id       AND e.session_id = NEW.session_id;     -- we do not modify data here     RETURN NEW; END; $select_insert$ LANGUAGE plpgsql;  CREATE TRIGGER select_insert_trg     BEFORE INSERT     ON scp_write_service.enrollee_select     FOR EACH ROW EXECUTE FUNCTION scp_write_service.select_insert();<\/code><\/pre>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 select_insert \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c (\u0432 \u043a\u043e\u0434\u0435 \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u0442, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u0434\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044e, \u043f\u0440\u0438\u0441\u044b\u043b\u0430\u0439\u0442\u0435 \u043f\u0443\u043b\u043b \u0440\u0435\u043a\u0432\u0435\u0441\u0442 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431). \u0412\u0442\u043e\u0440\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043f\u043e\u0434\u0430\u0447 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u0434\u0441\u0447\u0435\u0442\u043e\u043c \u0443\u0436\u0435 \u0438\u043c\u0435\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u0434\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u044f\u0432\u043b\u0435\u043d\u0438\u0439, \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u0442 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0441\u0432\u043e\u0435 \u043c\u043d\u0435\u043d\u0438\u0435 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0432\u043e\u0434\u0443, \u0434\u0430 \u0438 \u0441\u043f\u043e\u0441\u043e\u0431 \u044d\u0442\u043e\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u0421\u0423\u0411\u0414.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u043c\u0435\u044f \u0442\u0430\u043a\u043e\u0439 \u0442\u0440\u0438\u0433\u0433\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0440\u043e\u0441, \u043f\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u0441\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430:<\/p>\n<pre><code class=\"pgsql\">INSERT INTO scp_write_service.enrollee_select(user_id, session_id, spec_id)  VALUES (?, ?, ?)  ON CONFLICT DO NOTHING<\/code><\/pre>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432\u0435\u0440\u043d\u0435\u0442 1 \u0438\u043b\u0438 0, \u0447\u0442\u043e \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435: \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d, \u0443\u0436\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d \u0438\u043b\u0438 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u043e (\u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440).<\/p>\n<p>\u0422\u0430\u043a \u0436\u0435 \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u0430\u0447\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043e\u0442\u043a\u0430\u0437\u0430 \u043e\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u0435\u043d \u0432\u0442\u043e\u0440\u043e\u0439 \u0442\u0440\u0438\u0433\u0433\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439:<\/p>\n<pre><code class=\"pgsql\">CREATE FUNCTION scp_write_service.select_update()     RETURNS trigger AS $select_update$ DECLARE     previous UUID; BEGIN     IF OLD.status > NEW.status THEN         RAISE EXCEPTION 'Invalid status: %', NEW.status             USING HINT = 'status should be greater than previous value: ' || OLD.status;     ELSEIF OLD.status &lt;> NEW.status THEN         IF NEW.status = 1 THEN             NEW.confirmed_stamp = current_timestamp;              SELECT selected_spec_id             INTO previous             FROM scp_write_service.enrollee e             WHERE e.user_id = NEW.user_id               AND e.session_id = NEW.session_id;              IF previous IS NOT NULL THEN                 UPDATE scp_write_service.enrollee_select e                 SET canceled_stamp = current_timestamp,                     modified_stamp = current_timestamp,                     status         = 2,                     ordinal        = ordinal + 1,                     state          = 0                 WHERE e.user_id = NEW.user_id                   AND e.session_id = NEW.session_id                   AND e.spec_id = previous;             END IF;             UPDATE scp_write_service.enrollee e             SET selected_spec_id = NEW.spec_id,                 modified_stamp   = current_timestamp             WHERE e.user_id = NEW.user_id               AND e.session_id = NEW.session_id;         ELSEIF NEW.status = 2 THEN             NEW.canceled_stamp = current_timestamp;             UPDATE scp_write_service.enrollee e             SET selected_spec_id = NULL,                 modified_stamp   = current_timestamp             WHERE e.user_id = NEW.user_id               AND e.session_id = NEW.session_id               AND e.selected_spec_id = NEW.spec_id;         ELSE             -- prevent any status value different from 1 or 2             RAISE EXCEPTION 'Invalid status: %', NEW.status                 USING HINT = 'status must be 1 or 2';         END IF;     END IF;     IF OLD.status &lt;> NEW.status OR OLD.score &lt;> NEW.score THEN         NEW.ordinal = NEW.ordinal + 1;         NEW.state = 0;         NEW.modified_stamp = current_timestamp;     END IF;     -- otherwise changes performed by DB directly     -- and we should not affect those changes     -- (timeout for confirmation reached and state dropped to 0)     RETURN NEW; END; $select_update$ LANGUAGE plpgsql;  CREATE TRIGGER select_update_trg     BEFORE UPDATE     ON scp_write_service.enrollee_select     FOR EACH ROW EXECUTE FUNCTION scp_write_service.select_update(); <\/code><\/pre>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0447\u0442\u043e \u0441\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0435\u0441\u043b\u0438 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0441\u043e\u0433\u043b\u0430\u0441\u0438\u0435 \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0443\u0436\u0435 \u0438\u043c\u0435\u044f \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u0443\u0436\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e, \u043d\u043e \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043f\u0440\u043e\u0449\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0434\u043d\u043e \u043f\u043e\u043b\u0435, \u0430 \u0434\u0430\u043b\u044c\u0448\u0435 \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0441\u0430\u043c \u0432\u043d\u0435\u0441\u0435\u0442 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0440\u0430\u0432\u043a\u0438. \u0414\u0430 \u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u0443 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c:<\/p>\n<pre><code class=\"pgsql\">UPDATE scp_write_service.enrollee_select  SET status = 1 -- 1 is confirmed, 2 is cancelled WHERE user_id = ? AND spec_id = ? AND session_id = ?<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0447\u0442\u043e \u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0432 \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c:<\/p>\n<pre><code class=\"pgsql\">SELECT  user_id,         session_id,         spec_id,         status,         score,         created_stamp,         confirmed_stamp,         canceled_stamp,         ordinal FROM scp_write_service.enrollee_select es WHERE es.state = 0 ORDER BY es.modified_stamp LIMIT 128 OFFSET ?<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0434\u0430\u0442\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0442\u043e \u043f\u0435\u0440\u0432\u044b\u043c\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441\u0430\u043c\u044b\u0435 \u0441\u0442\u0430\u0440\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438. \u041f\u043e\u0441\u043b\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0432 \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (state) \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 1, \u0430 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0432 2.<\/p>\n<h2>\u041c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0414\u043b\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0443\u0434\u0430 \u043a\u0430\u043a \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u0437\u0430\u0442\u043e\u0447\u0435\u043d\u043d\u043e\u0439 \u043d\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435, \u0430 \u043d\u0435 \u0437\u0430\u043f\u0438\u0441\u044c \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0432\u0441\u0435 \u0438 \u0432\u0441\u044f. \u0422\u0430\u043a \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438\u0437 \u0434\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432, \u0430 \u043f\u0440\u0430\u0432\u043e\u043a \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043b\u044e\u0431\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0442\u043e \u0434\u043b\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u0430 \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u043e\u043d\u0430 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 \u0442\u0443 \u0436\u0435, \u0447\u0442\u043e \u0438 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438, \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435\u043c \u0432 \u0447\u0430\u0441\u0442\u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE scp_read_service.enrollee_select (     spec_id         UUID      NOT NULL,     session_id      INT       NOT NULL,     user_id         UUID      NOT NULL,     -- current selection status, 0 for applied, 1 for confirmed and 2 for cancelled     status          SMALLINT  NOT NULL DEFAULT 0,     -- the assigned user score     score           INT       NOT NULL DEFAULT 0,     -- stamp for creation(application) date     created_stamp   TIMESTAMP NOT NULL DEFAULT current_timestamp,     -- stamp for confirmation date     confirmed_stamp TIMESTAMP          DEFAULT NULL,     -- stamp for cancelled date     canceled_stamp  TIMESTAMP          DEFAULT NULL,      ---------------------------------------     --     integrity check fields        --     ---------------------------------------     -- last modification stamp received from write module     modified_stamp  TIMESTAMP NOT NULL DEFAULT current_timestamp,     -- should be treated like 'version', this way we will make     -- possible to reduce amount of response messages sent by target module     -- otherwise we'll deal with lots of duplicates     -- we should not write changes to database unless this column     -- has lower value than update     ordinal         SMALLINT           DEFAULT 0,     -- confirmation sent state, false - not sent, true - sent     state           BOOLEAN   NOT NULL DEFAULT FALSE,     -- we shift primary key column order to ensure that we may use primary key index for     -- queries     CONSTRAINT enrollee_select_pk PRIMARY KEY (spec_id, session_id, user_id) );<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043b\u043e\u043d\u043e\u043a \u0432 \u0433\u043b\u0430\u0432\u043d\u043e\u043c \u043a\u043b\u044e\u0447\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0430\u0436\u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0430 \u043d\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u0430 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c &#8212; \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<p>\u041f\u043e\u043b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f \u0431\u0443\u043b\u0435\u0432, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 (spec_id,session_id,user_id,ordinal) \u0438 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0443\u0436\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\/\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0438\u0437 \u0448\u0438\u043d\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"pgsql\">INSERT INTO scp_read_service.enrollee_select     AS es(         status,         score,         created_stamp,         confirmed_stamp,         canceled_stamp,         user_id,         session_id,         spec_id,         ordinal         ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) -- 9 params ON CONFLICT (spec_id, session_id, user_id) DO UPDATE SET state = false,               modified_stamp = CURRENT_TIMESTAMP,               status = ?,               score = ?,               created_stamp = ?,               confirmed_stamp = ?,               canceled_stamp = ?,               ordinal = ?  -- 6 params WHERE   es.user_id = ?     AND es.session_id = ?     AND es.spec_id = ?     AND es.ordinal &lt; ? -- 4 params <\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443, \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0411\u0414 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c &#8212; \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u043e \u0438 \u043a\u0440\u0430\u0439\u043d\u0435 \u043d\u0435\u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0438\u0432\u043d\u043e, \u0442\u043e \u0432\u044b\u0433\u043e\u0434\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e UPSERT, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0430\u043c\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442 \u043f\u043e\u043b\u0435 \u0437\u0430 \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0440\u043e\u0441 &#8212; \u0438 \u043d\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0438\u0437 \u0421\u0423\u0411\u0414. \u042d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u0449\u0438\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0430 \u0432\u0441\u0442\u0430\u0432\u043a\u0443 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435. \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0430\u043b\u0438\u0430\u0441 \u043d\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u043d\u0430\u0447\u0435 \u0432 WHERE \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0439 \u0434\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u043b\u044f, \u0430\u0432\u0442\u043e\u0440 \u0434\u0440\u0443\u0433\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u044d\u0442\u043e \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u044c \u043d\u0435 \u0441\u043c\u043e\u0433.<\/p>\n<h2>\u041d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e Java-\u043a\u043e\u0434!<\/h2>\n<p>\u041a\u0430\u043a \u0443\u0436\u0435 \u0432\u044b\u0448\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u0435\u0441\u0442\u0438\u0441\u044c \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Spring Boot. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u0437\u043e\u0432 \u0438\u043b\u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0442\u0440\u0443\u0431 \u0432 \u043a\u043e\u0434\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0438 \u043b\u0435\u0433\u043a\u043e\u0435 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Hibernate \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0411\u0414 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u043e\u0434\u043d\u0430\u043a\u043e \u0443\u0434\u0430\u0440\u044f\u0442\u044c\u0441\u044f \u0432 jdbc \u0438 \u0440\u0443\u0447\u043a\u0430\u043c\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0432\u043f\u043e\u043b\u043e\u0442\u044c \u0434\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0421\u0423\u0411\u0414 &#8212; \u0442\u043e\u0436\u0435 \u0438\u0434\u0435\u044f \u043f\u043b\u043e\u0445\u0430\u044f. \u0418\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 JDBCTemplate+spring \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u043c.<\/p>\n<p>\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0430 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432:<\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/github.com\/lastrix\/scp-lib\" rel=\"noopener noreferrer nofollow\">scp-lib<\/a> &#8212; \u043e\u0431\u0449\u0438\u0439 \u043a\u043e\u0434, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0432\u0441\u0435\u043c\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/lastrix\/scp-write-service\" rel=\"noopener noreferrer nofollow\">scp-write-service<\/a> &#8212; \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u0438\u0435\u043c\u0430 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438 (\u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u044b \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u0438 \u0432\u0443\u0437 \u0432\u043d\u043e\u0441\u044f\u0442 \u043f\u0440\u0430\u0432\u043a\u0438 \u0432 \u044d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441);<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/lastrix\/scp-write-sender-service\" rel=\"noopener noreferrer nofollow\">scp-write-sender-service<\/a> &#8212; \u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/lastrix\/scp-read-service\" rel=\"noopener noreferrer nofollow\">scp-read-service<\/a> &#8212; \u0441\u0435\u0440\u0432\u0438\u0441 \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0445 \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438, \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u043c\u0438 \u0438 \u0442.\u0434.;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/lastrix\/scp-read-receiver-service\" rel=\"noopener noreferrer nofollow\">scp-read-receiver-service<\/a> &#8212; \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u0438\u0435\u043c\u0430 \u0438\u0437 \u0448\u0438\u043d\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0443\u0447\u0435\u0442\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0445 \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u043e\u0431 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0411\u0414.<\/p>\n<\/li>\n<\/ol>\n<p>\u0427\u0442\u043e \u0431\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c mvn install \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 scp-lib,\u0430 \u0437\u0430\u0442\u0435\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 scp-write-sender-service.<\/p>\n<h2>\u041f\u0440\u043e\u0435\u043a\u0442 scp-lib<\/h2>\n<p>\u041f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d \u043d\u0430 2 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 &#8212; \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 rest \u0438 \u0441 \u0431\u0434. \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0434\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0441\u0445\u0435\u043c\u0443 \u0432 \u0411\u0414, \u0447\u0442\u043e \u0431\u044b \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 (\u0432\u043a\u043b\u044e\u0447\u0430\u044f liquibase), \u043b\u0435\u0436\u0430\u043b\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u0438 \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u043d\u0435\u0441\u0442\u0438 \u043e\u0434\u043d\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u043c, \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b. \u041e\u0441\u043d\u043e\u0432\u0430 \u0432\u0437\u044f\u0442\u0430 \u0441\u043e <a href=\"https:\/\/stackoverflow.com\/a\/72872126\" rel=\"noopener noreferrer nofollow\">stackoverflow<\/a>.<\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0440\u0435\u0441\u0442\u043e\u043c \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439:<\/p>\n<ol>\n<li>\n<p>\u041e\u0431\u0435\u0440\u0442\u043a\u0438 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a;<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0430\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u043e\u043b\u0438 \u0432 jwt;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 json \u0438 \u0442.\u0434.<\/p>\n<\/li>\n<\/ol>\n<p>\u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043e\u0448\u0438\u0431\u043e\u043a. \u0412 Spring \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u043e\u0448\u0438\u0431\u043e\u043a \u0432 \u0440\u0435\u0441\u0442-\u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043e\u0434\u043d\u0430\u043a\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u0430\u043a ControllerAdvice \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0431\u0438\u043d, \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u043a\u0430\u043a-\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e. \u0422\u0430\u043a \u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a, \u0447\u0442\u043e \u0431\u044b \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0438 \u0432\u0441\u0435 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b (\u0445\u043e\u0442\u044f \u0431\u044b \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b) \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u043e\u0448\u0438\u0431\u043e\u043a &#8212; \u0442\u0430\u043a \u0444\u0440\u043e\u043d\u0442\u0443 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0433\u0430\u0434\u0430\u0442\u044c \u0438\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u0431\u0449\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0435\u043c\u0443 \u043b\u0443\u0447\u0448\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442. \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043d\u0430 \u043b\u044e\u0431\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443 \u0432\u044b\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c Unknown Error, \u0430 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c Oops!, \u0432\u043e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b \u043f\u0440\u0430\u0432\u0434\u0430 \u0436\u0435\u043b\u0430\u0435\u0442\u0435 \u0431\u044b\u0442\u044c \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u043d\u0430 \u041c \u0438\u043b\u0438 \u0416 \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0435 \u0433\u043e\u0432\u043e\u0440\u044f\u0442, \u0441\u043b\u0430\u0432\u0430 \u043e \u0432\u0430\u0441 \u0438\u0434\u0435\u0442 \u0432\u043f\u0435\u0440\u0435\u0434\u0438 \u0432\u0430\u0441 \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0436\u0430\u0436\u0434\u0435\u0442 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0441 \u0432\u0430\u043c\u0438?<\/p>\n<p>\u041e\u0431\u0449\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0445\u043e\u0440\u043e\u0448\u0430 \u0438 \u0434\u043b\u044f \u0442\u0435\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u043e\u043d\u0438 \u0441\u043c\u043e\u0433\u0443\u0442 \u0440\u0435\u0448\u0438\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u0435\u0437 \u043f\u0440\u0438\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u0433\u043e-\u043b\u0438\u0431\u043e.<\/p>\n<p>\u0427\u0442\u043e \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u0443\u044e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044e \u043e\u0448\u0438\u0431\u043e\u043a \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439:<\/p>\n<ol>\n<li>\n<p>\u0411\u0435\u0440\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441;<\/p>\n<\/li>\n<li>\n<p>\u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0435\u0441\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442, \u043f\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u043b\u0438 null, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430 \u0441\u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0447\u0438\u0442\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u0441\u0443\u043f\u0435\u0440\u043a\u043b\u0430\u0441\u0441 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c \u043f\u0443\u043d\u043a\u0442 1.<\/p>\n<\/li>\n<\/ol>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e 1 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u0422\u043e\u0433\u0434\u0430 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0431\u0443\u0434\u0435\u0442:<\/p>\n<pre><code class=\"java\">public interface ErrorConverter&lt;E extends Throwable> {     ErrorObject toErrorObject(E e); }<\/code><\/pre>\n<p>\u0410 \u0447\u0442\u043e \u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u0443, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c &#8212; \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430 (\u0435\u0441\u043b\u0438 \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u044e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 ErrorConverter):<\/p>\n<pre><code class=\"java\">    private static Map&lt;Class&lt;?>, ErrorConverter&lt;Throwable>> createConverters() {         HashMap&lt;Class&lt;?>, ErrorConverter&lt;Throwable>> map = new HashMap&lt;>();         ServiceLoader.load(ErrorConverter.class)                 .forEach(c -> map.put(resolveExceptionType(c), c));         return map;     }      private static Class&lt;?> resolveExceptionType(ErrorConverter&lt;?> c) {         for (Type type : c.getClass().getGenericInterfaces()) {             if (type instanceof ParameterizedType &amp;&amp; ((ParameterizedType) type).getRawType().equals(ErrorConverter.class)) {                 return (Class&lt;?>) ((ParameterizedType) type).getActualTypeArguments()[0];             }         }         throw new IllegalStateException(\"Unable to determine handled error type for class: \" + c.getClass().getTypeName());     }<\/code><\/pre>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043a\u0430\u0440\u0442\u0443 \u0432 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u043e\u043b\u0435 (\u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e), \u0438 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044e:<\/p>\n<pre><code class=\"java\">    public static ErrorObject asErrorObject(Throwable e) {         return tryConvertRecursive(e, e.getClass());     }      private static ErrorObject tryConvertRecursive(Throwable e, Class&lt;?> aClass) {         var c = CONVERTERS.get(aClass);         if (c != null) {             var o = c.toErrorObject(e);             if (o != null) {                 return o;             }         }         return tryConvertRecursive(e, aClass.getSuperclass());     }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0436\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439 \u0432\u0438\u0434:<\/p>\n<pre><code class=\"java\">public class DataIntegrityViolationExceptionConverter implements ErrorConverter&lt;DataIntegrityViolationException> {     @Override     public ErrorObject toErrorObject(DataIntegrityViolationException e) {         if (e.getCause() instanceof ConstraintViolationException) {             return parseConstraintViolationException((ConstraintViolationException) e.getCause());         }         return null;     }      private ErrorObject parseConstraintViolationException(ConstraintViolationException e) {         if (e.getCause() instanceof BatchUpdateException) {             return parseBatchUpdateException((BatchUpdateException) e.getCause());         } else if (e.getCause() instanceof PSQLException) {             return parsePSQLException((PSQLException) e.getCause());         }         return null;     }      private ErrorObject parsePSQLException(PSQLException e) {         if (e.getMessage() != null &amp;&amp; e.getMessage().startsWith(\"ERROR: duplicate key value violates unique constraint\")) {             ServerErrorMessage se = e.getServerErrorMessage();             return ErrorObject.builder()                     .id(UUID.randomUUID().toString())                     .code(SystemError.CONSTRAINT_VIOLATION.getId())                     .description(SystemError.CONSTRAINT_VIOLATION.getDescription())                     .meta(se.getDetail())                     .stackTrace(ErrorObjectUtil.stackTrace2List(e))                     .build();         }         return ErrorObject.builder()                 .id(UUID.randomUUID().toString())                 .code(SystemError.COULD_NOT_EXECUTE_STATEMENT.getId())                 .description(SystemError.COULD_NOT_EXECUTE_STATEMENT.getDescription())                 .meta(e.getMessage())                 .stackTrace(ErrorObjectUtil.stackTrace2List(e))                 .build();     }      private ErrorObject parseBatchUpdateException(BatchUpdateException e) {         if (e.getCause() instanceof PSQLException) {             return parsePSQLException((PSQLException) e.getCause());         }         return null;     } }<\/code><\/pre>\n<h2>\u041f\u0440\u043e\u0435\u043a\u0442\u044b scp-write-service \u0438 scp-read-service<\/h2>\n<p>\u041e\u0431\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445. \u041a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e \u0441\u0443\u0442\u0438 \u0441\u0432\u043e\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u043f\u0438\u0441\u044f\u043c\u0438 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u0430, \u0432\u0442\u043e\u0440\u043e\u0439 &#8212; \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0445 \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 scp-write-service \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0447\u0442\u043e \u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0440\u0443\u0447\u043a\u0438 \u0434\u043b\u044f \u0444\u0440\u043e\u043d\u0442\u0430. \u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0438 \u0447\u0430\u0441\u0442\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442 \u043f\u0440\u043e http \u043c\u0435\u0442\u043e\u0434\u044b, \u0442\u043e \u0432\u0430\u043c \u0432\u0441\u0435 \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435 &#8212; \u043d\u0430\u0441\u043b\u0430\u0436\u0434\u0430\u0439\u0442\u0435\u0441\u044c:<\/p>\n<pre><code class=\"java\">    @RequireRoles(\"USER\")     @Timed(value = \"enrollee_info\")     @GetMapping     @Schema(description = \"Get full information about your selections\")     public Rest&lt;EnrolleeInfo> info() {         return Rest.of(srv.getInfo(jwt.getUserId(), null));     }      @RequireRoles(\"USER\")     @Timed(value = \"enrollee_enroll\")     @PostMapping(\"\/{spec}\")     @Schema(description = \"Enroll to speciality, enrolling to same speciality multiple times gives false, status won't be changed\")     public Rest&lt;Boolean> enroll(@PathVariable UUID spec) {         return Rest.of(srv.enroll(jwt.getUserId(), spec, null));     }      @RequireRoles(\"USER\")     @Timed(value = \"enrollee_confirm\")     @PutMapping(\"\/{spec}\")     @Schema(description = \"Confirm your application to speciality, you can not confirm cancelled application or if you're not applied to spec\")     public Rest&lt;Boolean> confirm(@PathVariable UUID spec) {         return Rest.of(srv.confirm(jwt.getUserId(), spec, null));     }      @RequireRoles(\"USER\")     @Timed(value = \"enrollee_cancel\")     @DeleteMapping(\"\/{spec}\")     @Schema(description = \"Cancel your application to speciality, you won't be able to interact with this spec afterwards rendering this spec non-existent to you\")     public Rest&lt;Boolean> cancel(@PathVariable UUID spec) {         return Rest.of(srv.cancel(jwt.getUserId(), spec, null));     }<\/code><\/pre>\n<p>\u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f RequiresRoles &#8212; \u044d\u0442\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u0441\u043f\u0435\u043a\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442 \u0432 jwt \u0442\u043e\u043a\u0435\u043d\u0435 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u043e\u043b\u0435\u0439. Timed &#8212; \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0440\u0443\u0447\u043a\u0438, \u0447\u0442\u043e \u0431\u044b \u043f\u043e\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0418 \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e swagger &#8212; \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f Schema \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u043c\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0437\u0434\u043d\u0435\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e \u0435\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0443 \/documentation\/v3\/api-docs.<\/p>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 EnrolleeService \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0441\u0435\u0441\u0441\u0438\u044e, \u0430 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<pre><code class=\"java\">    @Transactional     @Override     public boolean enroll(UUID userId, UUID specId, Integer sessionId) {         if (sessionId == null) {             sessionId = sessionDao.getLatestSessionId();         }         return enrolleeDao.enroll(userId, specId, sessionId);     }<\/code><\/pre>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0432\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u0411\u0414 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e \u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0411\u0414 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432.<\/p>\n<p>\u0421\u0430\u043c\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0434\u0430\u043d\u043d\u044b\u043c (dao, repository). \u0427\u0442\u043e \u0431\u044b \u043d\u0435 \u0437\u0430\u0442\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u043d\u0430 PostgreSQL, \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c, \u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u043b\u044f Postgres \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439.<\/p>\n<p>\u041d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u0434\u0430\u0447\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f:<\/p>\n<pre><code class=\"java\">    public boolean enroll(UUID userId, UUID specId, int sessionId) {         \/\/ we should prevent conflicts here and return false if nothing inserted         return 1 == jdbcTemplate.update(                 \"INSERT INTO scp_write_service.enrollee_select(user_id, session_id, spec_id) VALUES (?, ?, ?) ON CONFLICT DO NOTHING\",                 userId, sessionId, specId);     }<\/code><\/pre>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043b\u043e\u0436\u044c \u0438\u043b\u0438 \u0438\u0441\u0442\u0438\u043d\u0443, \u0435\u0441\u043b\u0438 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442 \u0443\u0436\u0435 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u0438\u043b\u0438 \u043e\u043d \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u0414\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0443 ON CONFLICT DO NOTHING, \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432\u0435\u0440\u043d\u0435\u0442 0, \u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430 \u0435\u0434\u0438\u043d\u0438\u0446\u0435 \u0432\u044b\u0434\u0430\u0441\u0442 \u043b\u043e\u0436\u044c. \u0415\u0441\u043b\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438\u043b\u0438 \u0441\u0435\u0441\u0441\u0438\u044f, \u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0430.<\/p>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430:<\/p>\n<pre><code class=\"yaml\">########## Framework related configuration goes here ################ db:   schema: 'scp_write_service'  management:   endpoints:     web:       exposure:         include: 'prometheus,health,info,metric'  spring:   profiles:     active: 'prod'   application:     name: 'scp-write-service'   liquibase:     enabled: 'true'     change-log: 'classpath:liquibase\/changelog\/changelog.xml'     liquibase-schema: '${db.schema}'     default-schema: '${db.schema}'   datasource:     driver-class-name: 'org.postgresql.Driver'     url: \"${SCP_WS_DB_URL}\"     username: \"${SCP_WS_DB_USERNAME}\"     password: \"${SCP_WS_DB_PASSWORD}\"     hikari:       connection-timeout: 10000   sql:     init:       mode: 'always'  server:   port: \"${SCP_WS_HTTP_PORT:8080}\"   servlet:     encoding:       charset: 'UTF-8'       force-response: 'true'  ########## Application related configuration goes here ############## scp:   debug: \"${SCP_WS_DEBUG:false}\"<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u043c\u0435\u0442\u0440\u0438\u043a \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 prometheus, \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u043a\u0446\u0438\u044e management. \u0412\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 SCP_WS_ (\u0435\u0441\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 SCP_), \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0440\u043e\u0449\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u0432\u0441\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u0434\u0430 \u0438 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0434\u043b\u044f \u043b\u044e\u0434\u0435\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0435 \u043f\u043e\u0432\u0438\u043d\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u043c\u0443 \u0448\u0430\u0431\u043b\u043e\u043d\u0443. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043b\u0443\u0447\u0448\u0435, \u0447\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0441 \u0438\u043c\u0435\u043d\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0441\u043f\u0440\u0438\u043d\u0433\u0430 (\u043d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e server.port \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f SERVER_PORT). \u0423 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u0430 \u0435\u0441\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043b\u044e\u0441\u044b, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0447\u0430\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u0435 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438.<\/p>\n<p>\u0422\u0430\u043a \u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0432 \u044d\u0442\u043e\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0435 \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438\u043b\u0438 \u0441\u0435\u0441\u0441\u0438\u0438 \u043f\u0440\u0438\u0435\u043c\u043d\u043e\u0439 \u043a\u043e\u043c\u043c\u0438\u0441\u0438\u0438, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u0430 \u043d\u0430 \u0443\u0447\u0430\u0441\u0442\u0438\u0435 \u0432 \u0441\u0435\u0441\u0441\u0438\u0438. \u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0430\u043a\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u0442.\u043a. \u0432\u0441\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0411\u0414. <\/p>\n<p>\u0414\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0447\u0442\u0435\u043d\u0438\u044f \u0442\u0430\u043a \u0436\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430:<\/p>\n<pre><code class=\"java\">@RestController @RequestMapping(\"\/api\/v1\/{sessionId}\/spec\") public class SpecController {     \/\/ ...      @RequireRoles(\"USER\")     @Timed(\"spec_slice\")     @PostMapping(\"\/{specId}\")     @Schema(description = \"Retrieve slice of application for selected speciality and selection campaign\")     public Rest&lt;EnrolleeSelect> slice(             @PathVariable UUID specId,             @PathVariable int sessionId,             @RequestBody Pagination pagination) {         return Rest.of(srv.slice(specId, sessionId, pagination), pagination);     }      @RequireRoles(\"USER\")     @Timed(\"spec_total\")     @GetMapping(\"\/{specId}\/total\")     @Schema(description = \"Get total number of applications for selected speciality and selection campaign\")     public Rest&lt;Long> total(@PathVariable UUID specId, @PathVariable int sessionId) {         return Rest.of(srv.getTotal(specId, sessionId));     }<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 (\u0434\u043e 625 \u043c\u043b\u043d), \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0442\u0440\u0430\u0442, \u0447\u0442\u043e \u0431\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0442\u043e\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 \u0432\u0438\u0434\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0440\u0443\u0447\u043a\u0438, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u0431\u044b \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u0411\u0414 \u0440\u0430\u0434\u0438 \u043e\u0434\u043d\u0438\u0445 \u0438 \u0442\u0435\u0445 \u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e.<\/p>\n<p>\u0424\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0447\u0442\u043e \u0431\u044b \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432\u0441\u0435\u0445, \u043a\u0442\u043e \u043e\u0442\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043e\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u043d\u0430 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 Pagination, \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0446\u0438\u043a\u043b\u0430 \u0441\u0442\u0430\u0442\u0435\u0439 \u044d\u0442\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<h2>\u041f\u0440\u043e\u0435\u043a\u0442\u044b scp-write-sender-service \u0438 scp-read-receiver-service<\/h2>\n<p>\u041e\u0431\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0438 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442 \u0441\u0445\u043e\u0436\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0438\u0448\u0435\u0442 \u0432 \u043a\u0430\u0444\u043a\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u043e\u0432 \u0438 \u0447\u0438\u0442\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0438. \u0412\u0442\u043e\u0440\u043e\u0439 \u0447\u0438\u0442\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f &#8212; \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u043e\u0432 \u0438 \u043f\u0438\u0448\u0435\u0442, \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432 \u0411\u0414, \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u0438\u0438.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u044b \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430, \u0434\u043b\u044f \u043e\u0431\u043e\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u044b \u043e\u0431\u0449\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 &#8212; \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0438 \u043f\u0440\u0438\u0435\u043c. \u0418\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u0447\u0442\u043e \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439 \u0442\u043e\u043f\u0438\u043a, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e \u043c\u0430\u0441\u043a\u0435, \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u043d\u043e\u0439 \u043a \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0443 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u043d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439 \u0442\u043e\u043f\u0438\u043a \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0439, \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043f\u043e \u0447\u0438\u0441\u043b\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u043e\u043c\u0443 \u043f\u0443\u0442\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u043a\u0438 \u043a \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041b\u043e\u0433\u0438\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u0442\u043e\u043f\u0438\u043a\u043e\u0432 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0430, \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430.<\/p>\n<p>\u041a\u0430\u043a \u0440\u0430\u043d\u0435\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043f\u0430\u043a\u0435\u0442\u044b &#8212; \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u0437\u0430\u043c\u0435\u0434\u043b\u0435\u043d\u0438\u044e \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e \u043c\u0435\u0440\u0435 \u0440\u043e\u0441\u0442\u0430 \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 (\u0430 \u0435\u0441\u043b\u0438 \u0442\u043e\u0447\u043d\u0435\u0435, \u0442\u043e \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u043f\u0438\u0441\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u0430\u043c\u0438 \u044f\u0432\u043b\u044f\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u0438 \u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0435\u0441\u0442\u044c. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0443\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 \u0434\u043e\u043b\u0433\u043e\u0439 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u043e\u0439 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. <\/p>\n<p>\u0421\u0430\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043c\u043e\u0436\u0435\u0442 (\u043d\u043e \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043f\u043e\u0440\u043e\u0433\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0431\u044b \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u043e\u043f\u0438\u043a\u0438 \u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u0437\u0430\u043f\u0438\u0441\u0438, \u0438\u043d\u0430\u0447\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u0442\u0430\u043a\u0430\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f, \u0447\u0442\u043e \u043e\u0434\u043d\u0430 \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0434\u0430\u0447 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u0447\u0442\u0438 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e). \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0442\u0438 \u0434\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u043d\u043e \u043f\u043e \u043c\u0435\u0440\u0435 \u0440\u043e\u0441\u0442\u0430 \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0435, \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438, \u0447\u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0442\u0438 \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u043a\u043b\u0438\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u043e \u0441\u0435\u0442\u0438. \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0435\u0440\u0438\u043e\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0432\u0435\u043d M\/L * T, \u0433\u0434\u0435 M &#8212; \u0447\u0438\u0441\u043b\u043e \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0447\u0442\u0435\u043d\u0438\u044f, L &#8212; \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u0430 T &#8212; \u043f\u0435\u0440\u0438\u043e\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0432 \u0442\u043e\u043f\u0438\u043a \u043f\u0440\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0435. \u0422\u0430\u043a \u043a\u0430\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u0440\u0430\u0432\u043d\u043e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0435, \u0442\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e T \u0431\u0443\u0434\u0435\u0442 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0442\u044c\u0441\u044f \u0441 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435\u043c M, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e c\/M, \u0433\u0434\u0435 c &#8212; \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430 \u0437\u0430\u0434\u0430\u044e\u0449\u0430\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0445 \u0432 \u043c\u043e\u0434\u0443\u043b\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445: \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u0435\u043b\u0438\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430 \u043f\u043e\u0442\u043e\u043a \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u0437 \u0411\u0414 \u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0442\u043e\u043f\u0438\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u043c\u0438 \u043e\u0431\u0449\u0438\u0439 \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438. \u041f\u043e\u0442\u043e\u043a \u0447\u0442\u0435\u043d\u0438\u044f \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0438\u0437 \u0411\u0414 \u0432\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e\u0434\u043b\u0435\u0436\u0430\u0449\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0438\u0445 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044f\u043c\u0438. \u041f\u043e\u0442\u043e\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u044b\u0442\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043c\u043e\u0433\u0443\u0442 \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435\u043c \u0441\u0432\u0435\u0440\u0445\u0443, \u0447\u0442\u043e \u0431\u044b \u0434\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0430\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f. \u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0442\u043e\u043f\u0438\u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0442\u043e\u043a\u0430 \u0447\u0442\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0411\u0414.<\/p>\n<h2>\u041a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 scp-write-sender-service<\/h2>\n<p>\u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0432 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043c\u0435\u0436\u0434\u0443 \u0442\u043e\u043f\u0438\u043a\u0430\u043c\u0438.<\/p>\n<pre><code class=\"java\">    public void doBackground() {         while (running) {             try {                 commit();                 int i = 10;                 \/\/ try fetching 10 times if possible, we must commit afterwards                 while (running &amp;&amp; i > 0 &amp;&amp; shouldFetch() &amp;&amp; fetch()) {                     i--;                 }                 if (i == 10) LockSupport.parkNanos(sleepTime);             } catch (Throwable e) {                 log.error(\"Failed to process\", e);                 waitOnError();             }         }     }<\/code><\/pre>\n<p>doBackground &#8212; \u044d\u0442\u043e \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0442\u043e\u043a\u0430 \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u0437 \u0411\u0414, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043c\u043e\u0436\u0435\u0442. \u0415\u0441\u043b\u0438 \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c, \u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u043f\u043e\u0442\u043e\u043a\u0430, \u043d\u043e \u043d\u0435 \u0447\u0435\u0440\u0435\u0437 Thread.sleep, \u0430 LockSupport.parkNanos &#8212; \u044d\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043b\u0435\u0433\u043a\u043e \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0437\u0430\u0442\u0435\u043c \u0440\u0430\u0437\u0431\u0443\u0434\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043b\u0443\u0447\u0448\u0435, \u0447\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c wait\/notify.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0447\u0438\u0442\u0430\u0442\u044c \u0438\u0437 \u0411\u0414 \u0434\u0430\u043d\u043d\u044b\u0435, \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u042d\u0442\u043e \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"java\">    private void commit() {         \/\/ flush all changes to persistent storage         while (!commitQueue.isEmpty()) {             \/\/ 32 items updated in batch per transaction             List&lt;T> changes = fetchFromQueue(commitQueue, 32);             source.commit(changes);             fetchCount -= changes.size();         }     }<\/code><\/pre>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u0434\u043e\u043b\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0446\u0438\u043a\u043b\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u043a\u0430 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u0437\u044f\u0442\u043e \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u041e\u0434\u043d\u0430\u043a\u043e \u043e\u043d \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0447\u0442\u0435\u043d\u0438\u0435 \u0438\u0437 \u0411\u0414 \u043d\u043e\u0432\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<\/p>\n<pre><code class=\"java\">    private boolean fetch() {         boolean empty = false;         int page = 0;         int fetched = 0;         \/\/ we collect messages from database till page contains no more         \/\/ elements, or we reached our buffer size         while (!empty &amp;&amp; fetchCount &lt; MAX_FETCH) {             var c = source.fetch(page);             registerChanges(c);             page++;             fetched += c.size();             empty = c.isEmpty();         }         return fetched > 0;     }<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u0437 \u0411\u0414 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u0437 \u0411\u0414. \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0443\u0436\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0430 \u0432 \u0411\u0414, \u0442\u043e \u043e\u043d\u0430 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435, \u0442.\u0435. \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043f\u043e\u043b\u0437\u0435\u0442 \u0438 \u0435\u0441\u0442\u044c \u0448\u0430\u043d\u0441 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u041a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0438 \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c &#8212; \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f. \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0446\u0438\u043a\u043b\u0435 \u0447\u0442\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u0430 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430, \u0445\u043e\u0442\u044c \u0438 \u0441 \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438.<\/p>\n<p>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u0442 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0438\u0445 \u0446\u0435\u043b\u0435\u0432\u043e\u043c\u0443 \u0442\u043e\u043f\u0438\u043a\u0443 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p>\u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0437\u0430\u0434\u0430\u0447\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0442\u043e\u043f\u0438\u043a \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439:<\/p>\n<pre><code class=\"java\">private void doWork() {             boolean _stopped = true;             try {                 \/\/ we should process at max maxProcessingChunk messages                 \/\/ and then reschedule ourselves in order to let other                 \/\/ channels to be processed                 int processed = 0;                 while (running &amp;&amp; !isEmpty() &amp;&amp; processed &lt; maxProcessingChunk) {                     processed += sendMessages();                 }                 if (isEmpty()) {                     notifyFetcher();                 } else {                     workPool.submit(this::doWork);                     _stopped = false;                 }             } catch (Throwable e) {                 log.error(\"Unable to send messages\", e);                 \/\/ this would block out fork join pool thread from processing further                 \/\/ in case of error it is okay                 waitOnError();             } finally {                 stopped = _stopped;             }         }          private int sendMessages() {             List&lt;T> w;             synchronized (q) {                 w = fetchFromQueue(q, 128);             }             var r = sender.send(w, channel);             commitQueue.addAll(r);             \/\/ source messages used because we need to ensure that             \/\/ if something goes bad with this channel - others will get their             \/\/ place, otherwise we'll lock here indefinitely             int processed = w.size();             log.info(\"Successfully sent {} of {} messages to channel {}\", r.size(), processed, channel);             \/\/ if something was not sent - we must reschedule it             if (r.size() != w.size()) {                 w.removeAll(r);                 addAll(w);             }             return processed;         }          public void addAll(List&lt;T> l) {             synchronized (q) {                 q.addAll(l);                 if (stopped &amp;&amp; !q.isEmpty()) {                     stopped = false;                     workPool.submit(this::doWork);                 }             }         } <\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0448\u0438\u043d\u044b \u0434\u0430\u043d\u043d\u044b\u0445 (\u043c\u043e\u0436\u043d\u043e \u0438 \u0440\u0435\u0441\u0442\u0430\u043c\u0438 \u0434\u043e\u043b\u0431\u0438\u0442\u044c \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441), \u0442\u043e \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e:<\/p>\n<pre><code class=\"java\">public interface ChangeSender&lt;T> {     List&lt;T> send(List&lt;T> changes, int channel); }<\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0432 kafka \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u0449\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e:<\/p>\n<pre><code class=\"java\">    public List&lt;T> send(List&lt;T> changes, int channel) {         var topic = topicTemplate + channel;         List&lt;T> results = Collections.synchronizedList(new ArrayList&lt;>(changes.size()));         CountDownLatch latch = new CountDownLatch(changes.size());         \/\/ we should map messages before send         \/\/ this way we may be sure that in case of json serialization exception         \/\/ no message sent to kafka         var list = changes.stream().map(x -> ImmutablePair.of(x, toJson(x))).toList();         \/\/ essentially we are trying to send as many messages as possible, this method         \/\/ should be called with multiple messages to work efficiently, otherwise kafka         \/\/ may refuse to send them right away because buffer is not full enough or not         \/\/ enough time passed from last send         for (var p : list) {             kafkaTemplate.send(topic, p.getValue())                     \/\/ handle result, count down latch and register object in results                     \/\/ if success                     \/\/ &lt;some code here>                     ;         }         awaitLatch(latch);         return results;     }<\/code><\/pre>\n<p>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043a\u0430\u0444\u043a\u0443 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u043e\u043d\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0442\u043e\u043f\u0438\u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u043a\u043e\u043f\u0438\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u0439\u0442 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u043e\u0442\u043f\u0430\u0432\u0440\u043a\u0438 \u0438\u043b\u0438 \u043d\u0435 \u0432\u044b\u0439\u0434\u0435\u0442 \u0442\u0430\u0439\u043c\u0430\u0443\u0442. \u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0438\u0441\u0438, \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0438 \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043d\u0430\u043a\u043e\u043f\u0438\u0442\u0441\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043d\u0435\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u043d\u0438 \u043f\u0438\u0448\u0443\u0442\u0441\u044f \u0432\u0441\u0435 \u043f\u043e\u0434\u0440\u044f\u0434, \u0430 \u0437\u0430\u0442\u0435\u043c \u0436\u0434\u0435\u043c, \u043f\u043e\u043a\u0430 CountDownLatch \u0434\u043e\u0439\u0434\u0435\u0442 \u0434\u043e 0, \u0447\u0442\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0432\u0441\u0435\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.<\/p>\n<h2>\u041a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 scp-read-receiver-service<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u043b\u0430 \u043e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u0438 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c, \u0442\u043e \u043f\u0440\u0438\u0435\u043c \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u0441\u0435 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442. \u041c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e \u0447\u0438\u0442\u0430\u0435\u0442 \u0438\u0437 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0438 \u043e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e \u043f\u0438\u0448\u0435\u0442 \u0432 \u0411\u0414.<\/p>\n<pre><code class=\"java\">    private void doSink() {         while (running) {             try {                 timer.update();                 while (shouldCommit()) {                     doCommit();                     timer.update();                 }                 LockSupport.parkNanos(DURATION_SINK_WAIT);             } catch (Throwable e) {                 log.error(\"Failed to process\", e);                 waitOnError();             }         }     }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 &#8212; \u043f\u043e\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0411\u0414 &#8212; \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0435\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438\u043b\u0438 \u043f\u0440\u043e\u0448\u043b\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0446\u0438\u043a\u043b \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u043f\u0438\u0448\u0435\u0442 \u0432 \u0411\u0414. \u0415\u0441\u043b\u0438 \u0438\u0437 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u044c, \u0442\u043e \u0446\u0438\u043a\u043b \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e.<\/p>\n<pre><code class=\"java\">    private void doCommit() {         Object slab = null;         List&lt;T> list = new ArrayList&lt;>(maxSinkChunkSize);         int processed = 0;         synchronized (queue) {             while (list.size() &lt; sinkChunkSize &amp;&amp; !queue.isEmpty()) {                 ChangeChunk&lt;T> chunk = queue.poll();                 for (T c : chunk.changes()) {                     \/\/ there is no need to commit same messages                     \/\/ again, so we skip them and reduce our                     \/\/ storage strain significantly                     if (idSet.add(idOf(c))) list.add(c);                 }                 \/\/ when update is done we should send this object                 \/\/ back to receiver in order to commit state                 slab = chunk.slab();                 \/\/ because there is no way to understand                 \/\/ how many messages we may process when                 \/\/ queue registration occurs, we should                 \/\/ do it here, that is why we are not                 \/\/ using list.size() later                 processed += chunk.changes().size();             }         }         sink.commit(list); \/\/ to database         commitSlab.set(slab); \/\/ commit offsets to kafka         synchronized (queue) {             messageQueueSize -= processed;         }         timer.updateAndReset(DURATION_ONE_SECOND.toMillis());     }<\/code><\/pre>\n<p>\u0421\u0430\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0411\u0414 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u044c \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041e\u043d\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e. \u0414\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u043d\u0435\u043a\u043e\u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e \u0442\u043e\u0447\u043a\u0430 \u043a\u043e\u043c\u043c\u0438\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0437\u0443\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0434\u043d\u0435\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b \u0434\u0430\u0431\u044b \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0442\u0435 \u0436\u0435 \u0441\u0430\u043c\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0435\u0449\u0435 \u0440\u0430\u0437 (\u0434\u043b\u044f \u043a\u0430\u0444\u043a\u0438 \u044d\u0442\u043e \u043e\u0444\u0444\u0441\u0435\u0442\u044b \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439).<\/p>\n<p>\u0425\u043e\u0442\u044f \u043f\u0440\u0438\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e \u0431\u044b \u043a\u0430\u0436\u0434\u0443\u044e \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044e \u0447\u0438\u0442\u0430\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435, \u0430\u0432\u0442\u043e\u0440 \u043d\u0435 \u0440\u0430\u0441\u043a\u043e\u043f\u0430\u043b \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e. \u0411\u0435\u0437 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043a\u0430\u0444\u043a\u043e\u0439 \u043d\u0435 \u0443\u0434\u0430\u0435\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u043e\u043a, \u0430 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440 \u0443\u0436\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u0437 \u0432\u0441\u0435\u0445 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0441\u0440\u0430\u0437\u0443, \u0447\u0442\u043e \u043d\u0435 \u0435\u0441\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u043e, \u043d\u043e \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0439 \u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u043f\u043e\u0434 \u0441\u0442\u0430\u0442\u044c\u0435\u0439 &#8212; \u0441\u043e\u0439\u0434\u0435\u0442.<\/p>\n<pre><code class=\"java\">    private void doReceive() {         while (running) {             try {                 commitReceive();                 int i = 10;                 while (running &amp;&amp; i > 0 &amp;&amp; shouldReceive() &amp;&amp; doReceiveUnsafe()) {                     i--;                 }                 \/\/ if no receive occured                 if (i == 10) LockSupport.parkNanos(DURATION_SINK_WAIT);             } catch (Throwable e) {                 log.error(\"Failed to process\", e);                 waitOnError();             }         }     }     private void commitReceive() {         Object o = commitSlab.get();         if (o != null) {             receiver.commit(o);             \/\/ replace that value with null to prevent us             \/\/ from sending same commit again             commitSlab.compareAndSet(o, null);         }     }<\/code><\/pre>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430 \u043f\u0440\u0438\u0435\u043c\u0430 \u043f\u0440\u043e\u0441\u0442\u0430 &#8212; \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043e\u0444\u0444\u0441\u0435\u0442\u044b \u0432 \u043a\u0430\u0444\u043a\u0443, \u0430 \u0437\u0430\u0442\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0438\u0442\u044c \u0447\u0442\u0435\u043d\u0438\u0435.<\/p>\n<pre><code class=\"java\">    private boolean doReceiveUnsafe() {         ChangeChunk&lt;T> chunk = receiver.receive(receiveBufferSize, RECEIVE_TIMEOUT);         \/\/ we double-check running here to prevent further work         if (running &amp;&amp; !chunk.isEmpty()) {             synchronized (queue) {                 queue.add(chunk);                 messageQueueSize += chunk.changes().size();                 if (messageQueueSize > sinkChunkSize) LockSupport.unpark(sinkThread);             }             return true;         }         return false;     }<\/code><\/pre>\n<p>\u041a\u0430\u0436\u0434\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u0438\u0437 \u0440\u0435\u0441\u0438\u0432\u0435\u0440\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u0442\u043e\u0447\u043a\u0443 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0445 \u043e\u0431\u0435\u0440\u0442\u043a\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0441\u0440\u0430\u0437\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0411\u0414, \u0435\u0441\u043b\u0438 \u044d\u0442\u0430 \u043e\u0431\u0435\u0440\u0442\u043a\u0430 \u043d\u0435 \u043f\u0443\u0441\u0442\u0430. \u0422\u0430\u043a \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0443\u0434\u0438\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0411\u0414, \u0435\u0441\u043b\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0430 LockSupport.unpark.<\/p>\n<p>\u0420\u0435\u0441\u0438\u0432\u0435\u0440 \u0434\u043b\u044f \u043a\u0430\u0444\u043a\u0438 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u043d\u0430 ChangeSender \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0442\u043e\u0447\u0435\u043d\u043d\u044b\u0439 \u043d\u0430 \u043f\u0440\u0438\u0435\u043c:<\/p>\n<pre><code class=\"java\">    public ChangeChunk&lt;T> receive(int maxSize, Duration duration) {         var timer = Time.SYSTEM.timer(duration);         List&lt;T> changes = new ArrayList&lt;>();         Map&lt;TopicPartition, OffsetAndMetadata> slab = new HashMap&lt;>();         \/\/ we should try to receive as many messages as possible in one go         \/\/ this will help us afterwards by reducing commit calls to kafka         while (timer.notExpired() &amp;&amp; changes.size() &lt; maxSize) {             timer.update();             var rs = consumer.poll(timer.remainingMs());             for (ConsumerRecord&lt;String, String> r : rs) {                 var v = parser.apply(r.value());                 \/\/ parser may fail to parse value and return null                 if (v != null) {                     changes.add(v);                 }                 \/\/ for each message we must update our slab, that holds info                 \/\/ about each partition offset for commit                 slab.put(new TopicPartition(r.topic(), r.partition()), new OffsetAndMetadata(r.offset() + 1));             }         }         return new ChangeChunk&lt;>(changes, new Slab(slab));     }<\/code><\/pre>\n<p>\u0412 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u0447\u0438\u0442\u0430\u0442\u044c \u0438\u0437 \u0432\u0441\u0435\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043d\u0430\u043c \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430. \u0422\u043e\u0447\u043a\u0430 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0444\u0444\u0441\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u043c\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0435\u0435. \u0415\u0441\u043b\u0438 \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0438\u0437 json, \u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e, \u0441\u0447\u0438\u0442\u0430\u044f, \u0447\u0442\u043e \u043e\u043d\u043e \u043f\u0443\u0441\u0442\u043e\u0435.<\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0442\u044e\u043d\u0438\u043d\u0433 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u0449\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0430\u0432\u0442\u043e\u0440 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u0442 \u043e \u043d\u0435\u043b\u0435\u0433\u043a\u043e\u0439 \u0434\u043e\u043b\u0435 \u0434\u0435\u0432-\u043e-\u043f\u0441\u0430.<\/p>\n<p>P.S.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/d33\/62e\/c87\/d3362ec8740a5f2e83f404a9a790a1ca.jpeg\" width=\"1000\" height=\"400\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d33\/62e\/c87\/d3362ec8740a5f2e83f404a9a790a1ca.jpeg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/687588\/\"> https:\/\/habr.com\/ru\/post\/687588\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0430\u0432\u0442\u043e\u0440 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u043f\u0440\u0438\u0435\u043c\u043d\u043e\u0439 \u043a\u043e\u043c\u043c\u0438\u0441\u0438\u0438 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043c\u0438\u043b\u043b\u0438\u0430\u0440\u0434\u0430 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u043e\u0432 \u0437\u0430 \u043e\u0434\u0438\u043d \u0434\u0435\u043d\u044c. \u0412 \u044d\u0442\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0430\u0432\u0442\u043e\u0440 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Spring + JDBCTemplate \u0438 Kafka \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b.<\/p>\n<h2>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f<\/h2>\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044e \u0431\u044b\u043b\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0448\u0438\u043d\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0436\u0434\u0443 \u043c\u043e\u0434\u0443\u043b\u044f\u043c\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u0447\u0442\u0435\u043d\u0438\u044f. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0443\u0447\u0435\u0441\u0442\u044c, \u0447\u0442\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0438, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u0440\u043e\u0441\u0442\u0435 \u0447\u0438\u0441\u043b\u0430 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439 \u0432 \u043e\u0434\u0438\u043d \u0442\u043e\u043f\u0438\u043a \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u0430\u044f \u0447\u0438\u0441\u043b\u043e\u043c \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e\u043c\u043d\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u043d\u0430 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u043a \u043c\u043e\u0434\u0443\u043b\u044f\u043c \u0447\u0442\u0435\u043d\u0438\u044f, \u0442\u043e \u043f\u0440\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u043f\u0438\u043a\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 24\/7. <\/p>\n<figure class=\"full-width\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1. \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u043f\u0438\u043a\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438<\/figcaption><\/figure>\n<p>\u041d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 1 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0438 \u0442\u043e\u043f\u0438\u043a\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 N \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0432 L \u0442\u043e\u043f\u0438\u043a\u043e\u0432, \u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0448\u0438\u043d\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044e N \u043d\u0430 L. \u0427\u0442\u043e \u0431\u044b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0432 \u043e\u0434\u043d\u0443 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044e, \u0442\u0430\u043a \u0436\u0435 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0438 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u043f\u043e\u0437\u0436\u0435. \u0418\u0442\u043e\u0433\u043e, \u0438\u043c\u0435\u044f N*122 \u043c\u0431\/\u0441 &#8212; \u043e\u0431\u044a\u0435\u043c \u043e\u0431\u0449\u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c N*L \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443, \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u0443\u043b\u044c\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0438 \u043e\u0431\u044b\u0447\u043d\u043e \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c\u0438 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0430\u043c\u0438.<\/p>\n<p>\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0432 \u0434\u0430\u043d\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0443 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u0434\u0435\u043d\u044c \u0441\u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430, \u0435\u0441\u043b\u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u043d\u0430 \u043b\u0438\u043d\u0435\u0439\u043d\u043e \u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0430 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u0442\u0430\u043a\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0440\u0430\u0432\u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0435 (\u0447\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0442\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0439 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u044b, \u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u0441\u0440\u0435\u0434\u043d\u0435\u043d\u0438\u044f). \u041f\u043e\u0441\u043b\u0435 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438 \u0431\u0435\u0441\u0441\u043e\u043d\u043d\u044b\u0445 \u043d\u043e\u0447\u0435\u0439 \u0432 \u043f\u043e\u0438\u0441\u043a\u0430\u0445 \u044d\u0442\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430, \u0430\u0432\u0442\u043e\u0440 \u043f\u0440\u0438\u0448\u0435\u043b \u043a \u0432\u044b\u0432\u043e\u0434\u0443, \u0447\u0442\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u043c\u0430 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a:<\/p>\n<figure class=\"full-width\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2. \u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0441\u0430\u043c\u044b\u0439 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441<\/figcaption><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u0436\u0435 \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u043e, \u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u0442\u0432\u0430 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0436\u0438\u0437\u043d\u0435\u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0415\u0441\u043b\u0438 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432, \u0441\u0435\u0442\u0435\u0439 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0442\u043e \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u0435\u0434\u0435\u043b (\u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0437\u0430\u043a\u043e\u043d\u0430\u043c \u0444\u0438\u0437\u0438\u043a\u0438, \u0430 \u0442\u043e\u0447\u043d\u0435\u0435 \u0440\u0430\u0434\u0438\u0443\u0441\u0443 \u0428\u0432\u0430\u0440\u0446\u0448\u0438\u043b\u044c\u0434\u0430), \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e-\u0432\u0440\u0435\u043c\u044f \u0441\u0445\u043b\u043e\u043f\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u0438\u043d\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c \u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0441\u0441\u043b\u0435\u0434\u043d\u043e.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043e\u0434\u043d\u0443 \u043e\u0446\u0435\u043d\u043a\u0443 \u0430\u0432\u0442\u043e\u0440 \u0434\u0430\u0442\u044c \u043c\u043e\u0436\u0435\u0442. \u0414\u0430\u043d\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0434\u043e\u043b\u0436\u043d\u043e \u0445\u0432\u0430\u0442\u0438\u0442\u044c \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u0442\u0432\u0443 \u043d\u0430 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0435 \u043f\u0430\u0440\u0443 \u043c\u043b\u043d \u043b\u0435\u0442 +- \u0441\u043e\u0442\u043d\u044e \u0442\u044b\u0441\u044f\u0447\u0435\u043b\u0435\u0442\u0438\u0439. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0434\u043b\u044f \u0432\u0430\u0441 \u0442\u0430\u043a\u043e\u0439 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0438 \u043d\u0435\u043f\u0440\u0438\u0435\u043c\u043b\u0438\u043c\u044b\u0439 &#8212; \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440\u0430\u043c. \u0410\u0432\u0442\u043e\u0440 \u0443\u0432\u0435\u0440\u0435\u043d, \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0434\u043e\u043b\u0433\u043e\u0441\u0440\u043e\u0447\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0427\u0442\u043e \u0431\u044b \u043d\u0435 \u0437\u0430\u0445\u043b\u0430\u043c\u043b\u044f\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438, \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440\u043e\u0432, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432\u0448\u0438\u0445 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435, \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 \u0441\u043f\u043e\u0439\u043b\u0435\u0440\u0435 \u043d\u0438\u0436\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440\u043e\u0432, \u0441\u043f\u0440\u0430\u0432\u0438\u0432\u0448\u0438\u0445\u0441\u044f \u0441 \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0435\u043c<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442 \u0431\u0430\u043d\u0430\u043d!<\/p>\n<h2>\u041c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438<\/h2>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/post\/579058\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u0431\u044b\u043b\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u043e\u0439 \u0411\u0414, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432\u0441\u0435 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b. \u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043c\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0421\u0430\u043c\u0430 \u0411\u0414 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043c\u043e\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. <\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0441\u0442\u0430\u0442\u0435\u0439, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043c\u043e\u0434\u0443\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438. <\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u043f\u0440\u0438\u0435\u043c\u043d\u044b\u0445 \u043a\u0430\u043c\u043f\u0430\u043d\u0438\u0439, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0442\u044c:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE scp_write_service.session (     session_id INT     NOT NULL,     active     BOOLEAN NOT NULL DEFAULT TRUE,     CONSTRAINT session_pk PRIMARY KEY (session_id) ); CREATE TABLE scp_write_service.spec (     spec_id UUID    NOT NULL,     active  BOOLEAN NOT NULL DEFAULT TRUE,     CONSTRAINT spec_pk PRIMARY KEY (spec_id) );<\/code><\/pre>\n<p>\u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0440\u0438\u0435\u043c\u043d\u044b\u0445 \u043a\u0430\u043c\u043f\u0430\u043d\u0438\u0439, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439. \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u044d\u0442\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044e. \u0425\u043e\u0442\u044f \u0434\u043b\u044f \u043f\u0440\u0438\u0435\u043c\u043d\u043e\u0439 \u043a\u0430\u043c\u043f\u0430\u043d\u0438\u0438 \u0444\u043b\u0430\u0433 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0443\u0436\u0435\u043d, \u0442\u043e \u0434\u043b\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 &#8212; \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d, \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u043d\u0430\u0447\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0411\u0414, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u0443\u044e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430. \u042d\u0442\u043e\u0442 \u0444\u043b\u0430\u0433 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043f\u0440\u0438\u0435\u043c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0439, \u043d\u0435 \u043d\u0430\u0440\u0443\u0448\u0430\u044f \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c \u0411\u0414.<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE scp_write_service.enrollee (     user_id          UUID      NOT NULL,     session_id       INT       NOT NULL,     -- if this user should no longer be able to perform any operation     disabled         BOOLEAN   NOT NULL DEFAULT FALSE,     -- selected speciality id     selected_spec_id UUID               DEFAULT NULL,     -- how much application may be sent by this enrollee     selection_count  SMALLINT  NOT NULL DEFAULT 20,     created_stamp    TIMESTAMP NOT NULL DEFAULT current_timestamp,     modified_stamp   TIMESTAMP NOT NULL DEFAULT current_timestamp,     CONSTRAINT enrollee_pk PRIMARY KEY (user_id, session_id),     CONSTRAINT enrollee_session_id_fk FOREIGN KEY (session_id) REFERENCES scp_write_service.session (session_id),     CONSTRAINT enrollee_selected_spec_id_fk FOREIGN KEY (selected_spec_id) REFERENCES scp_write_service.spec (spec_id),     CONSTRAINT enrollee_selection_count_positive_chk CHECK ( selection_count >= 0 ) );<\/code><\/pre>\n<p>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442\u0430 \u0445\u0440\u0430\u043d\u0438\u0442 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043d\u0435\u043c, \u0430 \u0442\u0430\u043a \u0436\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u044e\u0449\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u0442\u043e\u043a\u0435\u043d\u043e\u043c (\u0441\u0432\u043e\u0435\u0433\u043e \u0440\u043e\u0434\u0430). \u0422\u0430\u043a\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0443\u0447\u0430\u0441\u0442\u0438\u0435 \u0432 \u043f\u0440\u0438\u0435\u043c\u043d\u043e\u0439 \u043a\u0430\u043c\u043f\u0430\u043d\u0438\u0438 \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b. \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u043e\u0434\u0443\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u0435\u043b\u044f\u0442 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0442\u043e \u0434\u0430\u043d\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0442\u0438 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e.<\/p>\n<p>\u041f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 enrollee, \u0430\u0431\u0438\u0442\u0443\u0440\u0438\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u0432\u0435\u0434\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u043d\u0430\u043c \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0443\u0434\u0430\u0440\u0438\u0442\u0441\u044f \u0432 \u0441\u0445\u0435\u043c\u043e\u0442\u043e\u0437 \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u044b\u0435 \u0441\u0443\u043c\u043c\u044b \u0438\u043b\u0438 \u0435\u0449\u0435 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0431\u0435\u0437\u0443\u043c\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0436\u0435\u0447\u044c \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u044d\u043d\u0435\u0440\u0433\u0438\u044e \u0432 \u0441\u0442\u0438\u043b\u0435 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u043e\u0432, \u043e\u0434\u043d\u0430\u043a\u043e \u0430\u0432\u0442\u043e\u0440 \u0432\u044b\u0431\u0440\u0430\u043b \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442.<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE scp_write_service.enrollee_select (     user_id         UUID      NOT NULL,     session_id      INT       NOT NULL,     spec_id         UUID      NOT NULL,     -- current selection status, 0 for applied, 1 for confirmed and 2 for cancelled     status          SMALLINT  NOT NULL DEFAULT 0,     -- the assigned user score     score           INT       NOT NULL DEFAULT 0,     -- stamp for creation(application) date     created_stamp   TIMESTAMP NOT NULL DEFAULT current_timestamp,     -- stamp for confirmation date     confirmed_stamp TIMESTAMP          DEFAULT NULL,     -- stamp for cancelled date     canceled_stamp  TIMESTAMP          DEFAULT NULL,      ---------------------------------------     --     integrity check fields        --     ---------------------------------------     -- each time modification occurs, this stamp should be updated     modified_stamp  TIMESTAMP NOT NULL DEFAULT current_timestamp,     -- should be treated like 'version', this way we will make     -- possible to reduce amount of response messages sent by target module     -- otherwise we'll deal with lots of duplicates     ordinal         SMALLINT           DEFAULT 0,     -- current integrity check state, 0 - not sent, 1 - sent but not confirmed, 2 - sent and confirmed     state           SMALLINT  NOT NULL DEFAULT 0,      CONSTRAINT enrollee_select_pk PRIMARY KEY (user_id, session_id, spec_id),     CONSTRAINT enrollee_select_user_fk FOREIGN KEY (user_id, session_id) REFERENCES scp_write_service.enrollee (user_id, session_id),     CONSTRAINT enrollee_select_spec_fk FOREIGN KEY (spec_id) REFERENCES scp_write_service.spec (spec_id) );<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 (\u0430 \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0432 \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u043e\u0434\u0443\u043b\u044c \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b enrollee_select), \u043f\u043e\u043b\u0435 state \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 1, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430, \u043d\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0435\u0449\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e. \u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043b\u0435 ordinal \u0440\u0430\u0432\u043d\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u0436\u0435 \u043f\u043e\u043b\u044e \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 state \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 2, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u0431\u044b\u043b\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043e \u043f\u0440\u0438\u0435\u043c\u0435 \u043c\u043e\u0434\u0443\u043b\u0435\u043c \u0447\u0442\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u0443\u0437\u043d\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u0441\u0442\u0430\u0442\u0443\u0441.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435, \u0442\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0435 state \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 0, \u0447\u0442\u043e \u0431\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0435\u0449\u0435 \u0440\u0430\u0437. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u0440\u0430\u0437\u0443 \u0432\u043e \u0432\u0441\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0434\u043d\u043e\u0439. \u0427\u0442\u043e \u0431\u044b \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"pgsql\">UPDATE scp_write_service.enrollee_select SET    state = 0,    ordinal = ordinal + 1, -- we must change ordinal, otherwise read                          -- module won't send confirmation again   modified_stamp = CURRENT_TIMESTAMP WHERE state = 1    AND modified_stamp &lt; timezone('utc', now())::date - interval '1 hours'<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043d\u044f\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437 \u0432 15 \u043c\u0438\u043d\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u044d\u0442\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0411\u0414. \u0413\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e \u0431\u044b \u0435\u0433\u043e \u0437\u0432\u0430\u043b\u0438 \u041a\u0440\u043e\u043d\u043e\u0441 \u0438\u043b\u0438 \u0443 \u043d\u0435\u0433\u043e \u0431\u044b\u043b\u0430 \u043a\u0440\u043e\u043d-\u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0444\u0430\u043c\u0438\u043b\u0438\u044f, \u0438\u043d\u0430\u0447\u0435 \u043d\u0435 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>\u0414\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0411\u0414 \u0437\u0430\u0432\u0435\u0434\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043e\u043d\u0438 \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443.<\/p>\n<pre><code class=\"pgsql\">CREATE FUNCTION scp_write_service.select_insert()     RETURNS trigger AS $select_insert$ BEGIN     -- do not allow invalid parameters to be passed     -- confirmation or cancelling must be performed by<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-338474","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/338474","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=338474"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/338474\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=338474"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=338474"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=338474"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}