{"id":315657,"date":"2020-12-28T09:01:26","date_gmt":"2020-12-28T09:01:26","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=315657"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=315657","title":{"rendered":"@Transactional \u0432 Spring \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@Transactional<\/code><em> <\/em>\u0432 Spring \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f <em>\u041d\u0415 <\/em>\u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u0435\u043a. \u0421\u0442\u0430\u0442\u044c\u044f \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u0434 Spring 5.3 \u0438 Spring Boot 2.4<\/p>\n<h2>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/h2>\n<ul>\n<li>\n<p><a href=\"#locate\" rel=\"noopener noreferrer nofollow\">\u0413\u0434\u0435 \u043b\u0435\u0436\u0438\u0442 <\/a><code>@Transactional<\/code> <a href=\"#locate\" rel=\"noopener noreferrer nofollow\">\u0438 \u043a\u0430\u043a \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#infra\" rel=\"noopener noreferrer nofollow\">\u041a\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 <\/a><code>@Transactional<\/code><a href=\"#infra\" rel=\"noopener noreferrer nofollow\">?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#worker\" rel=\"noopener noreferrer nofollow\">\u041a\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 <\/a><code>@Transactional<\/code><a href=\"#worker\" rel=\"noopener noreferrer nofollow\">?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#sobes\" rel=\"noopener noreferrer nofollow\">\u041a\u0440\u0430\u0442\u043a\u043e \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 proxy \u0438\u043b\u0438 \u0441\u0430\u043c\u044b\u0439 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#run\" rel=\"noopener noreferrer nofollow\">\u041a\u0430\u043a \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f <\/a><code>@Transactional<\/code><a href=\"#run\" rel=\"noopener noreferrer nofollow\">?<\/a><\/p>\n<\/li>\n<li>\n<p><code>TransactionalManager<\/code> <a href=\"#manager\" rel=\"noopener noreferrer nofollow\">&#8212; \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#logs\" rel=\"noopener noreferrer nofollow\">\u041a\u0430\u043a \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043b\u043e\u0433\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#template\" rel=\"noopener noreferrer nofollow\">\u0418\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 (\u0447\u0435\u0440\u0435\u0437 TransactionTemplate)<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#hiber\" rel=\"noopener noreferrer nofollow\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0432 HibernateTransactionManager<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#reference\" rel=\"noopener noreferrer nofollow\">\u0421\u043f\u0438\u0441\u043e\u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432<\/a><\/p>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"locate\" id=\"locate\"><\/a><\/p>\n<h2>\u0413\u0434\u0435 \u043b\u0435\u0436\u0438\u0442 @Transactional \u0438 \u043a\u0430\u043a \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442?<\/h2>\n<p>\u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@Transactional<\/code> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 <code>org.springframework.transaction.annotation<\/code>, \u0442.\u0435. \u0435\u0435 \u043f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f <code>org.springframework.transaction.annotation.Transactional<\/code> \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e Spring Framework \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 1.2. \u041d\u0435 \u043f\u0443\u0442\u0430\u0439\u0442\u0435 \u0441 <code>javax.transaction.Transactional<\/code><em>. <\/em>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f Spring \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435. \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>javax.transaction.Transactional<\/code><em>  <\/em>Spring \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442, \u043d\u043e \u043b\u0443\u0447\u0448\u0435 \u0438\u0445 \u043d\u0435 \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0442\u044c \u0438, \u0435\u0441\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Spring, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u043e\u0434\u043d\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0430\u043a\u0435\u0442, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>\u0434\u043b\u044f maven<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"xml\">&lt;dependency&gt;  &lt;groupId&gt;org.springframework&lt;\/groupId&gt;  &lt;artifactId&gt;spring-tx&lt;\/artifactId&gt; &lt;\/dependency&gt;<\/code><\/pre>\n<\/p>\n<ul>\n<li>\n<p>\u0434\u043b\u044f gradle<\/p>\n<\/li>\n<\/ul>\n<pre><code>compile group: 'org.springframework', name: 'spring-tx', version: '5.3.2'<\/code><\/pre>\n<p>\u041d\u043e \u0441 \u043f\u0440\u0438\u0445\u043e\u0434\u043e\u043c Spring Boot \u0442\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c \u0443\u0436\u0435 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f &#8212; \u044d\u0442\u043e\u0442 \u043f\u0430\u043a\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432\u043e \u0432\u0441\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0435 starter-\u044b \u043a\u0430\u043a \u0442\u0440\u0430\u043d\u0437\u0438\u0442\u0438\u0432\u043d\u0430\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0438, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <em>spring-boot-starter-data-jpa<\/em>, \u0442\u043e <em>spring-tx<\/em> \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 <em>spring-data-jpa<\/em><\/p>\n<p><a class=\"anchor\" name=\"infra\" id=\"infra\"><\/a><\/p>\n<h2>\u041a\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 @Transactional?<\/h2>\n<p>\u0412 \u0442\u0435 \u0442\u0435\u043c\u043d\u044b\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0430, \u043a\u043e\u0433\u0434\u0430 \u0435\u0449\u0435 \u043d\u0435 \u0431\u044b\u043b\u043e Spring Boot, \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 <code>@Transactional<\/code> \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438 \u043d\u0430\u0434 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@EnableTransactionManager<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u0436\u0435 \u0447\u0430\u0441\u0442\u044c\u044e \u043f\u0430\u043a\u0435\u0442\u0430 <code>org.springframework.transaction.annotation<\/code>.<\/p>\n<p>\u042d\u0442\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><code>proxyTargetClass<\/code>(\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, false) &#8212; \u0431\u0443\u0434\u0435\u0442 \u043b\u0438 \u043f\u0440\u043e\u043a\u0441\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 CGLIB (true) \u0438\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 interface-based proxies (false). \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c true, <em>\u0412\u0421\u0415 <\/em>\u043e\u0431\u044a\u0435\u043a\u0442\u044b Spring (beans) \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 CGLIB, \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435, \u0447\u0442\u043e \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b <code>@Transactional<\/code> <\/p>\n<\/li>\n<li>\n<p><code>mode<\/code> (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e <code>AdviceMode.PROXY<\/code>) &#8212; \u043a\u0430\u043a \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u044b Advise. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b &#8212; <code>AdviceMode.PROXY<\/code> \u0438\u043b\u0438 <code>AdviceMode.ASPECTJ<\/code>. \u0415\u0441\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c AspectJ \u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0435\u0433\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c, \u0442\u043e \u043f\u0440\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u043e\u0434 \u0442\u0430\u043a, \u0447\u0442\u043e \u0442\u0435\u043b\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0443\u0436\u0435 \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u043e \u043a\u043e\u0434\u043e\u043c, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u043c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439. \u0415\u0441\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u043d <code>AdviceMode.PROXY<\/code> , \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f proxy \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. <strong> <\/strong>(\u043f\u0440\u0438\u043c\u0435\u0440 \u0441 <a href=\"http:\/\/sevenlist.github.io\/2014\/08\/24\/spring-at-transactional-with-aspectj\/\" rel=\"noopener noreferrer nofollow\">AspectJ<\/a>)<\/p>\n<\/li>\n<li>\n<p><code>order <\/code>&#8212; \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d advice. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, LOWEST_PRECEDENCE &#8212; \u0442.\u0435. \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0435 advice. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u0430\u0436\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 advice, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0435\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0442\u043e \u0436\u0435 \u044d\u0442\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0434\u0435\u043b\u0430\u0435\u0442? \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043d\u0435\u0435:<\/p>\n<pre><code class=\"java\">@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement {...}<\/code><\/pre>\n<p>\u041e\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 <code>TransactionManagementConfigurationSelector<\/code>, \u0440\u0430\u0431\u043e\u0442\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u0421 \u043f\u0440\u0438\u0445\u043e\u0434\u043e\u043c Spring Boot \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438<code>@EnableTransactionManager<\/code> \u043e\u0442\u043f\u0430\u043b\u0430. \u0422\u0435\u043f\u0435\u0440\u044c \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u0448\u043b\u043e \u0432 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c Spring Boot. \u041a\u0430\u043a \u0436\u0435 \u043e\u043d \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442?<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0435 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c <em>spring-boot-starter-\u0447\u0442\u043e-\u0442\u043e, <\/em>\u0442\u043e \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0437\u0438\u0442\u0438\u0432\u043d\u0430\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c &#8212; <em>spring-boot-autoconfigure<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0444\u0430\u0439\u043b\u0435 <em>spring.factories<\/em> \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0432\u0442\u043e-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439.  \u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 &#8212; \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/www.youtube.com\/watch?v=yy43NOreJG4\" rel=\"noopener noreferrer nofollow\">SpingBoot-\u043f\u043e\u0442\u0440\u043e\u0448\u0438\u0442\u0435\u043b\u044c \u043e\u0442 \u0411\u043e\u0440\u0438\u0441\u043e\u0432\u0430<\/a>.<strong> <\/strong>\u0412 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u0435\u0441\u0442\u044c \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438<\/p>\n<pre><code>org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration<\/code><\/pre>\n<p>\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u0430 \u043f\u0440\u0438 \u043f\u043e\u0434\u044a\u0435\u043c\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430. \u041f\u043e\u043b\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043d\u0438\u0436\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>TransactionAutoConfiguration<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@Configuration(proxyBeanMethods = false) @ConditionalOnClass(PlatformTransactionManager.class) @AutoConfigureAfter({JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,     DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class}) @EnableConfigurationProperties(TransactionProperties.class) public class TransactionAutoConfiguration {    @Bean   @ConditionalOnMissingBean   public TransactionManagerCustomizers platformTransactionManagerCustomizers(       ObjectProvider&lt;PlatformTransactionManagerCustomizer&lt;?&gt;&gt; customizers) {     return new TransactionManagerCustomizers(customizers.orderedStream().collect(Collectors.toList()));   }    @Bean   @ConditionalOnMissingBean   @ConditionalOnSingleCandidate(ReactiveTransactionManager.class)   public TransactionalOperator transactionalOperator(ReactiveTransactionManager transactionManager) {     return TransactionalOperator.create(transactionManager);   }    @Configuration(proxyBeanMethods = false)   @ConditionalOnSingleCandidate(PlatformTransactionManager.class)   public static class TransactionTemplateConfiguration {      @Bean     @ConditionalOnMissingBean(TransactionOperations.class)     public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {       return new TransactionTemplate(transactionManager);     }   }    @Configuration(proxyBeanMethods = false)   @ConditionalOnBean(TransactionManager.class)   @ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)   public static class EnableTransactionManagementConfiguration {      @Configuration(proxyBeanMethods = false)     @EnableTransactionManagement(proxyTargetClass = false)     @ConditionalOnProperty(prefix = \"spring.aop\", name = \"proxy-target-class\", havingValue = \"false\",         matchIfMissing = false)     public static class JdkDynamicAutoProxyConfiguration {     }      @Configuration(proxyBeanMethods = false)     @EnableTransactionManagement(proxyTargetClass = true)     @ConditionalOnProperty(prefix = \"spring.aop\", name = \"proxy-target-class\", havingValue = \"true\",         matchIfMissing = true)     public static class CglibAutoProxyConfiguration {     }   } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0430\u0432\u0442\u043e-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u043e \u0432 &#171;SpringBoot-\u043f\u043e\u0442\u0440\u043e\u0448\u0438\u0442\u0435\u043b\u044c&#187;, \u0437\u0434\u0435\u0441\u044c \u0443\u043f\u043e\u043c\u044f\u043d\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b.<\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0430\u0432\u0442\u043e-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e, \u0435\u0441\u043b\u0438 \u0432 <em>classpath <\/em>\u0435\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441  <code>PlatformTransactionManager<\/code>, \u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0434\u0430\u043b\u044c\u0448\u0435. \u0417\u0434\u0435\u0441\u044c \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f TransactionalOperator, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0432 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0435\u043a\u0435. <\/p>\n<p>\u041d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u0430\u0436\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043b\u0430\u0441\u0441  <code>EnableTransactionManagementConfiguration<\/code><\/p>\n<p>\u041e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0432\u0430 \u043f\u043e\u0434\u043a\u043b\u0430\u0441\u0441\u0430, \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u043e\u043d\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 <\/p>\n<pre><code>spring.aop.proxy-target-class<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 <code>spring.aop.proxy-target-class = true<\/code>, \u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@EnableTransactionManagement(proxyTargetClass = true)<\/code><\/p>\n<p>\u0415\u0441\u043b\u0438 <code>spring.aop.proxy-target-class = false<\/code>, \u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>EnableTransactionManagement(proxyTargetClass = false)<\/code><\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 spring-boot \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 <\/p>\n<pre><code>spring.aop.proxy-target-class=true<\/code><\/pre>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c CGLIB \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f proxy.<strong> <\/strong>(\u0421\u043e\u0432\u0435\u0442\u0443\u044e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/www.youtube.com\/watch?v=wpEPvAqnhZI&amp;t=2156s\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0442\u0435\u0440\u0432\u044c\u044e<\/a>, \u0433\u0434\u0435 \u0411\u043e\u0440\u0438\u0441\u043e\u0432 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u043e \u044d\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f Spring Boot).<\/p>\n<p><a class=\"anchor\" name=\"worker\" id=\"worker\"><\/a><\/p>\n<h2>\u041a\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 @Transactional?<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a\u0430\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 .<\/p>\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u043d\u0430 <\/p>\n<pre><code>@Import(TransactionManagementConfigurationSelector.class)<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@Import.<\/code> \u041e\u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0442\u0440\u0435\u0445 \u0442\u0438\u043f\u043e\u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 (component): <code>@Configuration<\/code>, <code>ImportSelector<\/code>, <code>ImportBeanDefinitionRegistrar<\/code>. <\/p>\n<p><code>TransactionManagementConfigurationSelector<\/code> , \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0434\u0435\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f, \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u043a <code>ImportSelector<\/code>. \u041f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043e\u043d, \u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u044f\u0441\u044c \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 <code>EnableTransactionManagement<\/code>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u0430\u043a\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435. \u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 <code>TransactionManagementConfigurationSelector<\/code>TransactionManagementConfigurationSelector.<\/p>\n<pre><code class=\"java\">public class TransactionManagementConfigurationSelector     extends AdviceModeImportSelector&lt;EnableTransactionManagement&gt; {    @Override   protected String[] selectImports(AdviceMode adviceMode) {     switch (adviceMode) {       case PROXY:         return new String[]{AutoProxyRegistrar.class.getName(),             ProxyTransactionManagementConfiguration.class.getName()};       case ASPECTJ:         return new String[]{determineTransactionAspectClass()};       default:         return null;     }   } .....<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439:<\/p>\n<p><code>AutoProxyRegistrar<\/code> &#8212; \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0438\u043d\u043e\u0432, <code>ProxyTransactionManagementConfiguration<\/code> &#8212; \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 <code>ProxyTransactionManagement<\/code>. <\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 <code>ProxyTransactionManagementConfiguration<\/code>. (\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u043a\u043e\u0434 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043d\u0438\u0436\u0435.  \u0425\u043e\u0442\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0435\u0433\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u0431\u0438\u043b\u043e)<\/p>\n<details class=\"spoiler\">\n<summary>ProxyTransactionManagementConfiguration<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@Configuration(proxyBeanMethods = false) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class ProxyTransactionManagementConfiguration     extends AbstractTransactionManagementConfiguration {    @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)   public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(       TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {      BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();     advisor.setTransactionAttributeSource(transactionAttributeSource);     advisor.setAdvice(transactionInterceptor);     if (this.enableTx != null) {       advisor.setOrder(this.enableTx.&lt;Integer&gt;getNumber(\"order\"));     }     return advisor;   }    @Bean   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)   public TransactionAttributeSource transactionAttributeSource() {     return new AnnotationTransactionAttributeSource();   }    @Bean   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)   public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {     TransactionInterceptor interceptor = new TransactionInterceptor();     interceptor.setTransactionAttributeSource(transactionAttributeSource);     if (this.txManager != null) {       interceptor.setTransactionManager(this.txManager);     }     return interceptor;   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f <em>bean<\/em> <em>transactionAttributeSource<\/em> \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 <code>AnnotationTransactionAttributeSource<\/code>. \u041e\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>TransactionAttributeSource.<\/code><\/p>\n<pre><code class=\"java\">public interface TransactionAttributeSource {    default boolean isCandidateClass(Class&lt;?&gt; targetClass) {     return true;   }    @Nullable   TransactionAttribute getTransactionAttribute(Method method,                                                @Nullable Class&lt;?&gt; targetClass); } <\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 <em>bean<\/em> \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043b\u0438 \u0433\u0434\u0435-\u0442\u043e <code>@Transactional<\/code> \u0438 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <em>propagation<\/em>) \u0434\u043b\u044f \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f <code>TransactionInterceptor<\/code>, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e  \u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043c\u0430\u0433\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 <code>BeanFactoryTransactionAttributeSourceAdvisor<\/code>, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f <code>TransactionInterceptor<\/code>. <\/p>\n<p><code>BeanFactoryTransactionAttributeSourceAdvisor<\/code> &#8212; \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 <em>PointcutAdvisor<\/em> (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043b \u0432 \u043e\u0434\u043d\u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c <em>advisor<\/em> and <em>pointcut<\/em>. \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/programmersought.com\/article\/5633162993\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a> <strong> <\/strong>\u0438\u043b\u0438 <a href=\"https:\/\/mkyong.com\/spring\/spring-aop-example-pointcut-advisor\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>,<strong> <\/strong>\u0438\u043b\u0438 \u0432 \u0432\u0438\u0434\u0435\u043e <a href=\"https:\/\/www.youtube.com\/watch?v=GL1txFxswHA\" rel=\"noopener noreferrer nofollow\">&#171;Spring patterns \u0434\u043b\u044f \u0432\u0437\u0440\u043e\u0441\u043b\u044b\u0445&#187;<\/a>.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043a\u0440\u0430\u0442\u0446\u0435 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0442\u043e <em>pointcut<\/em> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u0430\u043a\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0432 \u043d\u0438\u0445 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0430 <em>advice<\/em> &#8212; \u043a\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f.<\/p>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <em>pointcut<\/em> \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d <code>TransactionAttributeSource<\/code>,  \u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <em>advice<\/em> &#8212; <code>TransactionInterceptor<\/code>.<\/p>\n<p>\u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u0430 \u0433\u0434\u0435 \u0432\u0441\u0435\u043c\u0438 \u043b\u044e\u0431\u0438\u043c\u044b\u0439 <code>BeanPostProcessor<\/code>, \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c \u0442\u0430\u043a \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438?<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0430 \u0441\u0435\u0431\u044f \u0432\u0441\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0431\u0435\u0440\u0435\u0442 <code>InfrastructureAdvisorAutoProxyCreator<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043a \u0440\u0430\u0437 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>BeanPostProcessor<\/code>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/15c\/4d3\/2a1\/15c4d32a1834c01207d3922aaef45059\" alt=\"\u0418\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 InfrastructureAdvisorAutoProxyCreator\" title=\"\u0418\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 InfrastructureAdvisorAutoProxyCreator\" width=\"1328\" height=\"476\"><figcaption>\u0418\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 InfrastructureAdvisorAutoProxyCreator<\/figcaption><\/figure>\n<\/p>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 <code>@Transactional<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c Spring \u0438 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u043e\u0441\u043e\u0431\u043e\u0439 \u043c\u0430\u0433\u0438\u0438 \u0437\u0434\u0435\u0441\u044c \u043d\u0435\u0442. \u041f\u0440\u0438\u043c\u0435\u0440\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b (<a href=\"https:\/\/docs.spring.io\/spring-framework\/docs\/current\/reference\/html\/data-access.htm\" rel=\"noopener noreferrer nofollow\">\u0432\u0437\u044f\u0442\u0430 \u0438\u0437 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>)<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/425\/9d6\/2fd\/4259d62fd795448e9df21f525f52b4e6.png\" alt=\" \u041f\u0440\u0438\u043c\u0435\u0440\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b @Transactional\" title=\" \u041f\u0440\u0438\u043c\u0435\u0440\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b @Transactional\" width=\"600\" height=\"362\"><figcaption> \u041f\u0440\u0438\u043c\u0435\u0440\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b @Transactional<\/figcaption><\/figure>\n<h2>\u041a\u0440\u0430\u0442\u043a\u043e \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 proxy \u0438\u043b\u0438 \u0441\u0430\u043c\u044b\u0439 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0438<\/h2>\n<p>\u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0444\u0438\u0440\u043c\u0430\u0445, \u0433\u0434\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043b \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0432\u0430\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u043e\u043f\u0440\u043e\u0441:<\/p>\n<p>\u0414\u0430\u043d \u0441\u0435\u0440\u0432\u0438\u0441<\/p>\n<pre><code class=\"java\">@Service public class ServiceTest{   @Transactional   public void test1{       test2();   }    @Transactional(propagation = Propagation.REQUIRES_NEW)   public void test2(){   } }<\/code><\/pre>\n<p>\u0411\u0443\u0434\u0435\u0442 \u043b\u0438 \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 test2 \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u0430 test1 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u043d\u043e\u0432\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f?<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u044b\u0439  \u0438 \u043f\u043e\u043b\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b, \u0431\u044b\u043b \u0443\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u0432 <a href=\"https:\/\/habr.com\/ru\/post\/347752\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043d\u0430 habr<\/a>. \u0412 \u044d\u0442\u043e\u0439 \u0436\u0435 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438 \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0434\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u043d\u0430\u0448 bean \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c <em>\u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e<\/em> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434<\/p>\n<pre><code class=\"java\">public class Proxy{ \tprivate ServiceTest targetService;      public void test1{     \/\/\u043a\u043e\u0434 \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438     \/\/ ...       targetService.test2();     \/\/\u043a\u043e\u0434 \u043a\u043e\u043d\u0446\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438     \/\/ ...   }    public void test2(){     \/\/\u043a\u043e\u0434 \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438     \/\/ ...       targetService.test2();     \/\/\u043a\u043e\u0434 \u043a\u043e\u043d\u0446\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438     \/\/ ...   } }<\/code><\/pre>\n<\/p>\n<p>\u042d\u0442\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u044d\u0442\u043e\u0442 \u0440\u0438\u0441\u0443\u043d\u043e\u043a<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/efd\/b60\/ff7\/efdb60ff7dadeefd51d9293e42bbc7d4.jpg\" alt=\"\u0432\u0437\u044f\u0442\u043e \u0441 https:\/\/www.javainuse.com\/spring\/spring-boot-aop\" title=\"\u0432\u0437\u044f\u0442\u043e \u0441 https:\/\/www.javainuse.com\/spring\/spring-boot-aop\" width=\"484\" height=\"293\"><figcaption>\u0432\u0437\u044f\u0442\u043e \u0441 https:\/\/www.javainuse.com\/spring\/spring-boot-aop<\/figcaption><\/figure>\n<\/p>\n<p>\u0418 \u043e\u0442\u0441\u044e\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 test1 \u043a\u043e\u0434, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438, \u0432\u044b\u0437\u0432\u0430\u043d \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438 \u043d\u043e\u0432\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043d\u0435 \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 &#8212; \u043a\u043e\u0433\u0434\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 (\u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432).<\/p>\n<p><a class=\"anchor\" name=\"run\" id=\"run\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f @Transactional<\/h2>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u044d\u0442\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f. \u0417\u0434\u0435\u0441\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u044c \u0438\u0437 \u043d\u0438\u0445. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/habr.com\/ru\/company\/otus\/blog\/431508\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043d\u0430 habr<\/a> \u0438\u043b\u0438 \u0432 <a href=\"https:\/\/docs.spring.io\/spring-framework\/docs\/current\/javadoc-api\/org\/springframework\/transaction\/annotation\/Transactional.html\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 @Transactional<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p>propagation &#8212; \u0441\u043f\u043e\u0441\u043e\u0431 &#171;\u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f&#187; \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u044b\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b:<\/p>\n<p><code>MANDATORY <\/code>&#8212; \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f &#8212; \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043d\u0435\u0439, \u0438\u043d\u0430\u0447\u0435 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/p>\n<p><code>NESTED <\/code>&#8212; \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439  &#8212; \u0442\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e REQUIRED<\/p>\n<p><code>NEVER <\/code>&#8212; \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u043d\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f &#8212; \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/p>\n<p><code>NOT_SUPPORTED<\/code> &#8212; \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u043d\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 &#8212; \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f, \u043e\u043d\u0430 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f<\/p>\n<p><code>REQUIRED<\/code> &#8212; (\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e) &#8212; \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f, \u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043d\u0435\u0439, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442, \u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f<\/p>\n<p><code>REQUIRES_NEW<\/code>&#8212; \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f &#8212; \u0442\u043e \u043e\u043d\u0430 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f<\/p>\n<p><code>SUPPORTS<\/code> &#8212; \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f &#8212; \u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043d\u0435\u0439, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 &#8212; \u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u043e\u043d\u043d\u043e<\/p>\n<\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442\u043a\u0430\u0442\u043e\u043c<\/p>\n<\/li>\n<\/ul>\n<p><code>noRollbackFor <\/code>\u0438 <code>noRollbackForClassName  <\/code>&#8212; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u041d\u0415 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043a\u0430\u0442\u0430\u043d\u0430<\/p>\n<p><code>rollbackFor <\/code>\u0438 <code>rollbackForClassName  <\/code>&#8212; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u0411\u0423\u0414\u0415\u0422 \u043e\u0442\u043a\u0430\u0442\u0430\u043d\u0430<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a <code>TransactionInterceptor<\/code>, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u043a\u0430\u043a \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 \u0434\u043e Spring.<\/p>\n<p>\u041a\u043e\u0434 \u0432\u0437\u044f\u0442 \u0438\u0437 <a href=\"https:\/\/www.baeldung.com\/java-transactions\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0438 <\/a><\/p>\n<pre><code class=\"java\">Connection connection = DriverManager.getConnection(...); try {   connection.setAutoCommit(false);   PreparedStatement firstStatement = connection.prepareStatement(...);    firstStatement.executeUpdate();    PreparedStatement secondStatement = connection.prepareStatement(...);    secondStatement.executeUpdate();   connection.commit(); } catch (Exception e) {   connection.rollback(); } <\/code><\/pre>\n<p>\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ul>\n<li>\n<p>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 &#8212; DriverManager.getConnection(&#8230;)<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u043e\u0448\u0438\u0431\u043e\u043a &#8212; \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c commit (connection.commit())<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u0431\u044b\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 &#8212; \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a <code>TransactionInterceptor<\/code>. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#8212; <code>invoke<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 <code>invokeWithinTransaction <\/code>\u043a\u043b\u0430\u0441\u0441\u0430 <code>TransactionalAspectSupport<\/code><\/p>\n<p>\u0421\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043d\u0438\u0436\u0435<\/p>\n<pre><code class=\"java\">protected Object invokeWithinTransaction(Method method,                                          Class&lt;?&gt; targetClass,                                          final InvocationCallback invocation)    \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c TransactionManager tm \u0438 TransactionAttribute txAttr   \/\/ ...    if (this.reactiveAdapterRegistry != null &amp;&amp;       tm instanceof ReactiveTransactionManager) {     \/\/\u043a\u043e\u0434 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0441\u0442\u044d\u043a\u043e\u043c     \/\/ ...   }  PlatformTransactionManager ptm = asPlatformTransactionManager(tm); final String joinpointIdentification =   methodIdentification(method, targetClass, txAttr);  if (txAttr == null ||     !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {   \/\/ \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e   TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr,                                                         joinpointIdentification);    Object retVal;   try {     \/\/ \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438     retVal = invocation.proceedWithInvocation();   } catch (Throwable ex) {     \/\/ \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u0441\u044f, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e     completeTransactionAfterThrowing(txInfo, ex);     throw ex;   } finally {     \/\/ \u0447\u0438\u0441\u0442\u0438\u043c ThreadLocal \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435     cleanupTransactionInfo(txInfo);   }    if (retVal != null &amp;&amp; vavrPresent &amp;&amp; VavrDelegate.isVavrTry(retVal)) {     \/\/\u043a\u043e\u0434 \u0434\u043b\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 vavr     \/\/ ...   }    \/\/ \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c commit, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u043e\u0448\u0438\u0431\u043e\u043a   commitTransactionAfterReturning(txInfo);   return retVal; } else {   \/\/ \u043a\u043e\u0434 \u0434\u043b\u044f WebSphere   \/\/ ... } }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0442\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443. \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e:<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435\/\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e &#8212; createTransactionIfNecessary<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b &#8212; invocation.proceedWithInvocation<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u043e\u0448\u0438\u0431\u043e\u043a &#8212; \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c commitTransactionAfterReturning<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u0431\u044b\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 &#8212; \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f &#8212; completeTransactionAfterThrowing<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0430\u0436\u0434\u0443\u044e \u0447\u0430\u0441\u0442\u044c. <\/p>\n<p><em>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/em><\/p>\n<pre><code class=\"java\">protected TransactionInfo createTransactionIfNecessary   (PlatformTransactionManager tm, TransactionAttribute txAttr,    final String joinpointIdentification) {    if (txAttr != null &amp;&amp; txAttr.getName() == null) {     txAttr = new DelegatingTransactionAttribute(txAttr) {       @Override       public String getName() {         return joinpointIdentification;       }     };   }    TransactionStatus status = null;   if (txAttr != null) {     if (tm != null) {       status = tm.getTransaction(txAttr);     }   }   return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status); } <\/code><\/pre>\n<p>\u0418\u0437 \u0432\u0430\u0436\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u0437\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0437\u043e\u0432 <code>transactionalManager.getTransaction(...)<\/code>(\u0440\u0430\u0431\u043e\u0442\u0430 \u0441 <code>TransactionalManager <\/code>\u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u043f\u043e\u0437\u0436\u0435) \u0438 \u0432\u044b\u0437\u043e\u0432 <code>prepareTransactionInfo <\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f <code>txInfo.bindToThread()<\/code>; \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 <code>TransactionInfo <\/code>\u0432 <code>ThreadLocal <\/code>\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>transactionInfoHolder<\/code><em>, <\/em>\u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 <code>currentTransactionStatus<\/code><\/p>\n<p><em>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u043a\u0430\u0442\u043e\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439<\/em><\/p>\n<pre><code class=\"java\">protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {   if (txInfo != null &amp;&amp; txInfo.getTransactionStatus() != null) {     if (txInfo.transactionAttribute != null &amp;&amp;          txInfo.transactionAttribute.rollbackOn(ex)) {       try {         txInfo.getTransactionManager()           .rollback(txInfo.getTransactionStatus());       } catch (Exception ex) {         \/\/ ...       }     } else {       try {         txInfo.getTransactionManager()           .commit(txInfo.getTransactionStatus());       } catch (Exception ex) {         \/\/ ...       }     }   } } <\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u0430\u043a\u0442\u0438\u0432\u043d\u0430, \u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0430\u0434\u043e \u043b\u0438 \u0435\u0435 \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u044d\u0442\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435 \u043d\u0430\u0434\u043e, \u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u044e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 <code>commit(txInfo.getTransactionStatus())<\/code> \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 <code>txInfo.transactionAttribute.rollbackOn(ex)<\/code> . \u0412\u044b\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0431\u043b\u0438\u0437\u043a\u043e\u0435 \u043f\u043e \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<p> <em>\u0424\u0438\u043a\u0441\u0430\u0446\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/em><\/p>\n<pre><code class=\"java\">protected void commitTransactionAfterReturning(TransactionInfo txInfo) {   if (txInfo != null &amp;&amp;        txInfo.getTransactionStatus() != null) {     txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());   } } <\/code><\/pre>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u044f, \u0435\u0441\u043b\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u0430\u043a\u0442\u0438\u0432\u043d\u0430.<\/p>\n<p><a class=\"anchor\" name=\"manager\" id=\"manager\"><\/a><\/p>\n<h2>TransactionManager &#8212; \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435?<\/h2>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 <code>TransactionManager<\/code>, \u043c\u0430\u0440\u043a\u0438\u0440\u043e\u0432\u043e\u0447\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432. \u0415\u0433\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442 <code>ReactiveTransactionManager <\/code>\u0438 <code>PlatformTransactionManager<\/code><\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u0435\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439.<\/p>\n<pre><code class=\"java\">public interface PlatformTransactionManager extends TransactionManager {    TransactionStatus getTransaction(TransactionDefinition definition)     throws TransactionException;    void commit(TransactionStatus status) throws TransactionException;    void rollback(TransactionStatus status) throws TransactionException; }<\/code><\/pre>\n<p>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0435\u0433\u043e 3 \u043c\u0435\u0442\u043e\u0434\u0430 &#8212; \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, commit \u0438 rollback.<\/p>\n<p>Spring \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>AbstractPlatformTransactionManager<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e <code>propagation<\/code>.  \u041d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u043e \u0440\u0430\u0437\u043d\u043e\u043c\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u0435\u0433\u043e \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438. <\/p>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 <code>AbstractPlatformTransactionManager <\/code>\u0438 \u0435\u0433\u043e \u043f\u043e\u0434\u043a\u043b\u0430\u0441\u0441\u044b \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 org.<code>springframework.transaction.support.TransactionSynchronizationManage<\/code> \u0434\u043b\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u0430\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044f <em>connection<\/em>. \u0425\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043d\u0430\u0431\u043e\u0440\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 <em>ThreadLocal <\/em>\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. <\/p>\n<pre><code class=\"java\">private static final ThreadLocal&lt;Map&lt;Object, Object&gt;&gt; resources =   new NamedThreadLocal&lt;&gt;(\"Transactional resources\");  private static final ThreadLocal&lt;Set&lt;TransactionSynchronization&gt;&gt; synchronizations =   new NamedThreadLocal&lt;&gt;(\"Transaction synchronizations\");  private static final ThreadLocal&lt;String&gt; currentTransactionName =   new NamedThreadLocal&lt;&gt;(\"Current transaction name\");  private static final ThreadLocal&lt;Boolean&gt; currentTransactionReadOnly =   new NamedThreadLocal&lt;&gt;(\"Current transaction read-only status\");  private static final ThreadLocal&lt;Integer&gt; currentTransactionIsolationLevel =   new NamedThreadLocal&lt;&gt;(\"Current transaction isolation level\");  private static final ThreadLocal&lt;Boolean&gt; actualTransactionActive =   new NamedThreadLocal&lt;&gt;(\"Actual transaction active\");<\/code><\/pre>\n<p><a class=\"anchor\" name=\"logs\" id=\"logs\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043b\u043e\u0433\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439?<\/h2>\n<p>Spring  \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438: \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u0434\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f DEBUG \u0434\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u0430 <code>org.springframework.transaction<\/code> , \u0438 \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 hibernate, &#8212; <code>org.hibernate.transaction<\/code><\/p>\n<pre><code>logging:    level:       org.springframework.orm.jpa: DEBUG       org.springframework.transaction: DEBUG<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e, \u043e\u0431\u0440\u0430\u0449\u0430\u044f\u0441\u044c \u043a ThreadLocal \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440,<\/p>\n<pre><code class=\"java\">TransactionSynchronizationManager.isActualTransactionActive(); TransactionAspectSupport.currentTransactionStatus();<\/code><\/pre>\n<p><a class=\"anchor\" name=\"template\" id=\"template\"><\/a><\/p>\n<h2>\u0418\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 (\u0447\u0435\u0440\u0435\u0437 TransactionTemplate)<\/h2>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 \u0447\u0435\u0440\u0435\u0437 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438, Spring \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e Spring, \u043a\u0430\u043a \u0438 \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d &#171;Template&#187; (JdbcTemplate, RestTemplate). \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441 <code>TransactionTemplate<\/code>. Bean \u043f\u0440\u043e\u0434\u0435\u043a\u043b\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0432 <code>TransactionAutoConfiguration<\/code>. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 execute<\/p>\n<pre><code class=\"java\">public &lt;T&gt; T execute(TransactionCallback&lt;T&gt; action) throws TransactionException {    if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {     return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);   } else {     TransactionStatus status = this.transactionManager.getTransaction(this);     T result;     try {       result = action.doInTransaction(status);     } catch (RuntimeException | Error ex) {       rollbackOnException(status, ex);       throw ex;     } catch (Throwable ex) {       rollbackOnException(status, ex);       throw new UndeclaredThrowableException(ex, \"TransactionCallback threw undeclared checked exception\");     }     this.transactionManager.commit(status);     return result;   } }<\/code><\/pre>\n<p>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c rollback\/commit:<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e (getTransaction)<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 (doInTransaction)<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u0431\u044b\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430, \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u0441\u044f (rollbackOnException)<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u0432\u0441\u0435 \u0445\u043e\u0440\u043e\u0448\u043e, \u0442\u043e \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e (commit)<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430 \u0441\u0442\u0440\u043e\u0447\u043a\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 <\/p>\n<pre><code>this.transactionManager.getTransaction(this);<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a <code>transactionManager <\/code>\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438 <code>TransactionDefinition <\/code>(\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u0437\u043e\u0432\u043e\u043c execute), \u0442\u043e \u043e\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0435\u0431\u044f \u0432 <code>transactionManager<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b \u0432 <code>transactionManager<\/code>.<\/p>\n<p> \u0422\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f <code>TrsansactionStatus<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c, \u043d\u0435 \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/p>\n<pre><code class=\"java\">transactionTemplate.execute(new TransactionCallbackWithoutResult() {   protected void doInTransactionWithoutResult(TransactionStatus status) {     try {       updateOperation1();       updateOperation2();     } catch (SomeBusinessExeption ex) {       status.setRollbackOnly();     }   } });<\/code><\/pre>\n<p><a class=\"anchor\" name=\"hiber\" id=\"hiber\"><\/a><\/p>\n<h2>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0432 HibernateTransactionManager<\/h2>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 hibernate, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0439\u043c\u0430\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0443 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0435\u0435, \u0432\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0436\u0435 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043c\u0435\u0447\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a rollbackOnly (\u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 JdbcTemplate, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440). \u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043f\u043e\u0447\u0435\u043c\u0443?<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u043e\u0447\u0435\u043c\u0443? &#8212; \u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 JPA \u0432\u044b \u043d\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430, hibernate \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0447\u0442\u043e \u0435\u043c\u0443 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f, &#8212; \u043f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e \u043a\u0430\u043a rollbackOnly<\/p>\n<p>\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442? \u0415\u0441\u043b\u0438  hibernate \u043b\u043e\u0432\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0435\u0431\u044f \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <\/p>\n<pre><code>TransactionDriverControl().markRollbackOnly()<\/code><\/pre>\n<p>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0442\u0430\u0432\u0438\u0442 \u0444\u043b\u0430\u0433 &#8212; <code>rollbackOnly = true<\/code>, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0439\u043c\u0430\u043b\u0438 \u044d\u0442\u0443 \u043e\u0448\u0438\u0431\u043a\u0443 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438. \u041f\u043e \u043b\u043e\u0433\u0438\u043a\u0435 Spring, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>PlatformTransactionManager.commit<\/code><\/p>\n<p>\u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 <code>PlatformTransactionManager.commit<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u0445\u0440\u0430\u043d\u0438\u0442 \u0444\u043b\u0430\u0433:<\/p>\n<pre><code class=\"java\">unexpectedRollback = status.isGlobalRollbackOnly(); \/\/true doCommit(status); \/\/\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e  if (unexpectedRollback) { \/\/\u043a\u0438\u0434\u0430\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435   throw new UnexpectedRollbackException(     \"Transaction silently rolled back because it has been marked as rollback-only\"); } <\/code><\/pre>\n<p>doCommit \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043e\u0436\u0438\u0434\u0430\u0442\u044c, \u0447\u0442\u043e \u0445\u043e\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u043d\u043e hibernate \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043d\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 hibernate \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 <\/p>\n<pre><code class=\"java\">@Override public void commit() {   try {     \/\/\u0445\u043e\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0438 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f commit, \u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0442\u043a\u0430\u0442\u0430     if ( rollbackOnly ) {         try {         rollback();         \/\/...         return;       }       catch (RollbackException e) {         throw e;       }       catch (RuntimeException e) {         throw e;       }     }      JdbcResourceLocalTransactionCoordinatorImpl.this.beforeCompletionCallback();     jdbcResourceTransaction.commit();     \/\/ ... <\/code><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430 \u043e\u0442\u043a\u0430\u0442 \u0437\u0434\u0435\u0441\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 Hibernate, \u0430 \u043d\u0435 Spring, \u0445\u043e\u0442\u044f Spring \u0438 \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 PlatformTransactionManager.rollback<\/p>\n<p><a class=\"anchor\" name=\"reference\" id=\"reference\"><\/a><\/p>\n<h2>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b<\/h2>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=wpEPvAqnhZI&amp;t=2156s\" rel=\"noopener noreferrer nofollow\">\u0420\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u0435 \u0441\u0435\u043a\u0440\u0435\u0442\u043e\u0432 \u043e Spring Boot \u043e\u0442 \u0411\u043e\u0440\u0438\u0441\u043e\u0432\u0430<\/a><\/p>\n<p><a href=\"http:\/\/sevenlist.github.io\/2014\/08\/24\/spring-at-transactional-with-aspectj\/\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u044b c AspectJ<\/a><\/p>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=yy43NOreJG4\" rel=\"noopener noreferrer nofollow\">SpringBoot-\u043f\u043e\u0442\u0440\u043e\u0448\u0438\u0442\u0435\u043b\u044c<\/a><\/p>\n<p><a href=\"https:\/\/docs.spring.io\/spring-framework\/docs\/current\/reference\/html\/data-access.html#spring-data-tier\" rel=\"noopener noreferrer nofollow\">Spring reference<\/a><\/p>\n<p><a href=\"https:\/\/programmersought.com\/article\/5633162993\/\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Pointcut<\/a><\/p>\n<p><a href=\"https:\/\/mkyong.com\/spring\/spring-aop-example-pointcut-advisor\/\" rel=\"noopener noreferrer nofollow\">\u0415\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Pointcut<\/a><\/p>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=GL1txFxswHA\" rel=\"noopener noreferrer nofollow\">Spring patterns \u0434\u043b\u044f \u0432\u0437\u0440\u043e\u0441\u043b\u044b\u0445<\/a><\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/347752\/\" rel=\"noopener noreferrer nofollow\">Spring AOP. \u041c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0432\u043e\u043f\u0440\u043e\u0441\u0438\u043a \u0441 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f<\/a><\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/company\/otus\/blog\/431508\/\" rel=\"noopener noreferrer nofollow\">\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 \u0432 Spring<\/a><\/p>\n<p><a href=\"https:\/\/docs.spring.io\/spring-framework\/docs\/current\/javadoc-api\/org\/springframework\/transaction\/annotation\/Transactional.html\" rel=\"noopener noreferrer nofollow\">\u0421\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e @Transactional<\/a><\/p>\n<p><a href=\"https:\/\/www.baeldung.com\/java-transactions\" rel=\"noopener noreferrer nofollow\">Introducation to Transactional in Java and Spring<\/a><\/p>\n<\/div>\n<p> \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\/532000\/\"> https:\/\/habr.com\/ru\/post\/532000\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@Transactional<\/code><em> <\/em>\u0432 Spring \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f <em>\u041d\u0415 <\/em>\u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u0435\u043a. \u0421\u0442\u0430\u0442\u044c\u044f \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u0434 Spring 5.3 \u0438 Spring Boot 2.4<\/p>\n<h2>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/h2>\n<ul>\n<li>\n<p><a href=\"#locate\" rel=\"noopener noreferrer nofollow\">\u0413\u0434\u0435 \u043b\u0435\u0436\u0438\u0442 <\/a><code>@Transactional<\/code> <a href=\"#locate\" rel=\"noopener noreferrer nofollow\">\u0438 \u043a\u0430\u043a \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#infra\" rel=\"noopener noreferrer nofollow\">\u041a\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 <\/a><code>@Transactional<\/code><a href=\"#infra\" rel=\"noopener noreferrer nofollow\">?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#worker\" rel=\"noopener noreferrer nofollow\">\u041a\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 <\/a><code>@Transactional<\/code><a href=\"#worker\" rel=\"noopener noreferrer nofollow\">?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#sobes\" rel=\"noopener noreferrer nofollow\">\u041a\u0440\u0430\u0442\u043a\u043e \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 proxy \u0438\u043b\u0438 \u0441\u0430\u043c\u044b\u0439 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#run\" rel=\"noopener noreferrer nofollow\">\u041a\u0430\u043a \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f <\/a><code>@Transactional<\/code><a href=\"#run\" rel=\"noopener noreferrer nofollow\">?<\/a><\/p>\n<\/li>\n<li>\n<p><code>TransactionalManager<\/code> <a href=\"#manager\" rel=\"noopener noreferrer nofollow\">&#8212; \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#logs\" rel=\"noopener noreferrer nofollow\">\u041a\u0430\u043a \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043b\u043e\u0433\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#template\" rel=\"noopener noreferrer nofollow\">\u0418\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 (\u0447\u0435\u0440\u0435\u0437 TransactionTemplate)<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#hiber\" rel=\"noopener noreferrer nofollow\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0432 HibernateTransactionManager<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#reference\" rel=\"noopener noreferrer nofollow\">\u0421\u043f\u0438\u0441\u043e\u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432<\/a><\/p>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"locate\" id=\"locate\"><\/a><\/p>\n<h2>\u0413\u0434\u0435 \u043b\u0435\u0436\u0438\u0442 @Transactional \u0438 \u043a\u0430\u043a \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442?<\/h2>\n<p>\u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@Transactional<\/code> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 <code>org.springframework.transaction.annotation<\/code>, \u0442.\u0435. \u0435\u0435 \u043f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f <code>org.springframework.transaction.annotation.Transactional<\/code> \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e Spring Framework \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 1.2. \u041d\u0435 \u043f\u0443\u0442\u0430\u0439\u0442\u0435 \u0441 <code>javax.transaction.Transactional<\/code><em>. <\/em>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f Spring \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435. \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>javax.transaction.Transactional<\/code><em>  <\/em>Spring \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442, \u043d\u043e \u043b\u0443\u0447\u0448\u0435 \u0438\u0445 \u043d\u0435 \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0442\u044c \u0438, \u0435\u0441\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Spring, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u043e\u0434\u043d\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0430\u043a\u0435\u0442, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>\u0434\u043b\u044f maven<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"xml\">&lt;dependency&gt;  &lt;groupId&gt;org.springframework&lt;\/groupId&gt;  &lt;artifactId&gt;spring-tx&lt;\/artifactId&gt; &lt;\/dependency&gt;<\/code><\/pre>\n<\/p>\n<ul>\n<li>\n<p>\u0434\u043b\u044f gradle<\/p>\n<\/li>\n<\/ul>\n<pre><code>compile group: 'org.springframework', name: 'spring-tx', version: '5.3.2'<\/code><\/pre>\n<p>\u041d\u043e \u0441 \u043f\u0440\u0438\u0445\u043e\u0434\u043e\u043c Spring Boot \u0442\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c \u0443\u0436\u0435 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f &#8212; \u044d\u0442\u043e\u0442 \u043f\u0430\u043a\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432\u043e \u0432\u0441\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0435 starter-\u044b \u043a\u0430\u043a \u0442\u0440\u0430\u043d\u0437\u0438\u0442\u0438\u0432\u043d\u0430\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0438, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <em>spring-boot-starter-data-jpa<\/em>, \u0442\u043e <em>spring-tx<\/em> \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 <em>spring-data-jpa<\/em><\/p>\n<p><a class=\"anchor\" name=\"infra\" id=\"infra\"><\/a><\/p>\n<h2>\u041a\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 @Transactional?<\/h2>\n<p>\u0412 \u0442\u0435 \u0442\u0435\u043c\u043d\u044b\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0430, \u043a\u043e\u0433\u0434\u0430 \u0435\u0449\u0435 \u043d\u0435 \u0431\u044b\u043b\u043e Spring Boot, \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 <code>@Transactional<\/code> \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438 \u043d\u0430\u0434 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@EnableTransactionManager<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u0436\u0435 \u0447\u0430\u0441\u0442\u044c\u044e \u043f\u0430\u043a\u0435\u0442\u0430 <code>org.springframework.transaction.annotation<\/code>.<\/p>\n<p>\u042d\u0442\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><code>proxyTargetClass<\/code>(\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, false) &#8212; \u0431\u0443\u0434\u0435\u0442 \u043b\u0438 \u043f\u0440\u043e\u043a\u0441\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 CGLIB (true) \u0438\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 interface-based proxies (false). \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c true, <em>\u0412\u0421\u0415 <\/em>\u043e\u0431\u044a\u0435\u043a\u0442\u044b Spring (beans) \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 CGLIB, \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435, \u0447\u0442\u043e \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b <code>@Transactional<\/code> <\/p>\n<\/li>\n<li>\n<p><code>mode<\/code> (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e <code>AdviceMode.PROXY<\/code>) &#8212; \u043a\u0430\u043a \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u044b Advise. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b &#8212; <code>AdviceMode.PROXY<\/code> \u0438\u043b\u0438 <code>AdviceMode.ASPECTJ<\/code>. \u0415\u0441\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c AspectJ \u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0435\u0433\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c, \u0442\u043e \u043f\u0440\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u043e\u0434 \u0442\u0430\u043a, \u0447\u0442\u043e \u0442\u0435\u043b\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0443\u0436\u0435 \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u043e \u043a\u043e\u0434\u043e\u043c, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u043c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439. \u0415\u0441\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u043d <code>AdviceMode.PROXY<\/code> , \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f proxy \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. <strong> <\/strong>(\u043f\u0440\u0438\u043c\u0435\u0440 \u0441 <a href=\"http:\/\/sevenlist.github.io\/2014\/08\/24\/spring-at-transactional-with-aspectj\/\" rel=\"noopener noreferrer nofollow\">AspectJ<\/a>)<\/p>\n<\/li>\n<li>\n<p><code>order <\/code>&#8212; \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d advice. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, LOWEST_PRECEDENCE &#8212; \u0442.\u0435. \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0435 advice. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u0430\u0436\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 advice, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0435\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0442\u043e \u0436\u0435 \u044d\u0442\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0434\u0435\u043b\u0430\u0435\u0442? \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043d\u0435\u0435:<\/p>\n<pre><code class=\"java\">@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement {...}<\/code><\/pre>\n<p>\u041e\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 <code>TransactionManagementConfigurationSelector<\/code>, \u0440\u0430\u0431\u043e\u0442\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u0421 \u043f\u0440\u0438\u0445\u043e\u0434\u043e\u043c Spring Boot \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438<code>@EnableTransactionManager<\/code> \u043e\u0442\u043f\u0430\u043b\u0430. \u0422\u0435\u043f\u0435\u0440\u044c \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u0448\u043b\u043e \u0432 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c Spring Boot. \u041a\u0430\u043a \u0436\u0435 \u043e\u043d \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442?<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0435 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c <em>spring-boot-starter-\u0447\u0442\u043e-\u0442\u043e, <\/em>\u0442\u043e \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0437\u0438\u0442\u0438\u0432\u043d\u0430\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c &#8212; <em>spring-boot-autoconfigure<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0444\u0430\u0439\u043b\u0435 <em>spring.factories<\/em> \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0432\u0442\u043e-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439.  \u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 &#8212; \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/www.youtube.com\/watch?v=yy43NOreJG4\" rel=\"noopener noreferrer nofollow\">SpingBoot-\u043f\u043e\u0442\u0440\u043e\u0448\u0438\u0442\u0435\u043b\u044c \u043e\u0442 \u0411\u043e\u0440\u0438\u0441\u043e\u0432\u0430<\/a>.<strong> <\/strong>\u0412 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u0435\u0441\u0442\u044c \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438<\/p>\n<pre><code>org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration<\/code><\/pre>\n<p>\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u0430 \u043f\u0440\u0438 \u043f\u043e\u0434\u044a\u0435\u043c\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430. \u041f\u043e\u043b\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043d\u0438\u0436\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>TransactionAutoConfiguration<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@Configuration(proxyBeanMethods = false) @ConditionalOnClass(PlatformTransactionManager.class) @AutoConfigureAfter({JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,     DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class}) @EnableConfigurationProperties(TransactionProperties.class) public class TransactionAutoConfiguration {    @Bean   @ConditionalOnMissingBean   public TransactionManagerCustomizers platformTransactionManagerCustomizers(       ObjectProvider&lt;PlatformTransactionManagerCustomizer&lt;?&gt;&gt; customizers) {     return new TransactionManagerCustomizers(customizers.orderedStream().collect(Collectors.toList()));   }    @Bean   @ConditionalOnMissingBean   @ConditionalOnSingleCandidate(ReactiveTransactionManager.class)   public TransactionalOperator transactionalOperator(ReactiveTransactionManager transactionManager) {     return TransactionalOperator.create(transactionManager);   }    @Configuration(proxyBeanMethods = false)   @ConditionalOnSingleCandidate(PlatformTransactionManager.class)   public static class TransactionTemplateConfiguration {      @Bean     @ConditionalOnMissingBean(TransactionOperations.class)     public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {       return new TransactionTemplate(transactionManager);     }   }    @Configuration(proxyBeanMethods = false)   @ConditionalOnBean(TransactionManager.class)   @ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)   public static class EnableTransactionManagementConfiguration {      @Configuration(proxyBeanMethods = false)     @EnableTransactionManagement(proxyTargetClass = false)     @ConditionalOnProperty(prefix = \"spring.aop\", name = \"proxy-target-class\", havingValue = \"false\",         matchIfMissing = false)     public static class JdkDynamicAutoProxyConfiguration {     }      @Configuration(proxyBeanMethods = false)     @EnableTransactionManagement(proxyTargetClass = true)     @ConditionalOnProperty(prefix = \"spring.aop\", name = \"proxy-target-class\", havingValue = \"true\",         matchIfMissing = true)     public static class CglibAutoProxyConfiguration {     }   } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0430\u0432\u0442\u043e-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u043e \u0432 &#171;SpringBoot-\u043f\u043e\u0442\u0440\u043e\u0448\u0438\u0442\u0435\u043b\u044c&#187;, \u0437\u0434\u0435\u0441\u044c \u0443\u043f\u043e\u043c\u044f\u043d\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b.<\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0430\u0432\u0442\u043e-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e, \u0435\u0441\u043b\u0438 \u0432 <em>classpath <\/em>\u0435\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441  <code>PlatformTransactionManager<\/code>, \u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0434\u0430\u043b\u044c\u0448\u0435. \u0417\u0434\u0435\u0441\u044c \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f TransactionalOperator, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0432 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0435\u043a\u0435. <\/p>\n<p>\u041d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u0430\u0436\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043b\u0430\u0441\u0441  <code>EnableTransactionManagementConfiguration<\/code><\/p>\n<p>\u041e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0432\u0430 \u043f\u043e\u0434\u043a\u043b\u0430\u0441\u0441\u0430, \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u043e\u043d\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 <\/p>\n<pre><code>spring.aop.proxy-target-class<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 <code>spring.aop.proxy-target-class = true<\/code>, \u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@EnableTransactionManagement(proxyTargetClass = true)<\/code><\/p>\n<p>\u0415\u0441\u043b\u0438 <code>spring.aop.proxy-target-class = false<\/code>, \u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>EnableTransactionManagement(proxyTargetClass = false)<\/code><\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 spring-boot \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 <\/p>\n<pre><code>spring.aop.proxy-target-class=true<\/code><\/pre>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c CGLIB \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f proxy.<strong> <\/strong>(\u0421\u043e\u0432\u0435\u0442\u0443\u044e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/www.youtube.com\/watch?v=wpEPvAqnhZI&amp;t=2156s\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0442\u0435\u0440\u0432\u044c\u044e<\/a>, \u0433\u0434\u0435 \u0411\u043e\u0440\u0438\u0441\u043e\u0432 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u043e \u044d\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f Spring Boot).<\/p>\n<p><a class=\"anchor\" name=\"worker\" id=\"worker\"><\/a><\/p>\n<h2>\u041a\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 @Transactional?<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a\u0430\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 .<\/p>\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u043d\u0430 <\/p>\n<pre><code>@Import(TransactionManagementConfigurationSelector.class)<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@Import.<\/code> \u041e\u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0442\u0440\u0435\u0445 \u0442\u0438\u043f\u043e\u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 (component): <code>@Configuration<\/code>, <code>ImportSelector<\/code>, <code>ImportBeanDefinitionRegistrar<\/code>. <\/p>\n<p><code>TransactionManagementConfigurationSelector<\/code> , \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0434\u0435\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f, \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u043a <code>ImportSelector<\/code>. \u041f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043e\u043d, \u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u044f\u0441\u044c \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 <code>EnableTransactionManagement<\/code>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u0430\u043a\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435. \u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 <code>TransactionManagementConfigurationSelector<\/code>TransactionManagementConfigurationSelector.<\/p>\n<pre><code class=\"java\">public class TransactionManagementConfigurationSelector     extends AdviceModeImportSelector&lt;EnableTransactionManagement&gt; {    @Override   protected String[] selectImports(AdviceMode adviceMode) {     switch (adviceMode) {       case PROXY:         return new String[]{AutoProxyRegistrar.class.getName(),             ProxyTransactionManagementConfiguration.class.getName()};       case ASPECTJ:         return new String[]{determineTransactionAspectClass()};       default:         return null;     }   } .....<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439:<\/p>\n<p><code>AutoProxyRegistrar<\/code> &#8212; \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0438\u043d\u043e\u0432, <code>ProxyTransactionManagementConfiguration<\/code> &#8212; \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 <code>ProxyTransactionManagement<\/code>. <\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 <code>ProxyTransactionManagementConfiguration<\/code>. (\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u043a\u043e\u0434 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043d\u0438\u0436\u0435.  \u0425\u043e\u0442\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0435\u0433\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u0431\u0438\u043b\u043e)<\/p>\n<details class=\"spoiler\">\n<summary>ProxyTransactionManagementConfiguration<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@Configuration(proxyBeanMethods = false) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class ProxyTransactionManagementConfiguration     extends AbstractTransactionManagementConfiguration {    @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)   public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(       TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {      BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();     advisor.setTransactionAttributeSource(transactionAttributeSource);     advisor.setAdvice(transactionInterceptor);     if (this.enableTx != null) {       advisor.setOrder(this.enableTx.&lt;Integer&gt;getNumber(\"order\"));     }     return advisor;   }    @Bean   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)   public TransactionAttributeSource transactionAttributeSource() {     return new AnnotationTransactionAttributeSource();   }    @Bean   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)   <\/code><\/pre>\n<\/div>\n<\/details>\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-315657","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/315657","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=315657"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/315657\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=315657"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=315657"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=315657"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}