import{_ as p}from"./plugin-vue_export-helper.21dcd24c.js";import{r as o,o as i,c,a as n,b as t,e,d as a}from"./app.14d8ac59.js";const l={},u=e(`

\u5173\u4E8E\u4E8B\u52A1

\u4E8B\u52A1\u5728\u903B\u8F91\u4E0A\u662F\u4E00\u7EC4\u64CD\u4F5C\uFF0C\u8981\u4E48\u6267\u884C\uFF0C\u8981\u4E0D\u90FD\u4E0D\u6267\u884C\u3002\u4E3B\u8981\u662F\u9488\u5BF9\u6570\u636E\u5E93\u800C\u8A00\u7684\uFF0C\u6BD4\u5982\u8BF4 MySQL\u3002

\u53EA\u8981\u8BB0\u4F4F\u8FD9\u4E00\u70B9\uFF0C\u7406\u89E3\u4E8B\u52A1\u5C31\u5F88\u5BB9\u6613\u4E86\u3002\u5728 Java \u4E2D\uFF0C\u6211\u4EEC\u901A\u5E38\u8981\u5728\u4E1A\u52A1\u91CC\u9762\u5904\u7406\u591A\u4E2A\u4E8B\u4EF6\uFF0C\u6BD4\u5982\u8BF4\u6211\u4EEC\u6709\u4E00\u4E2A\u4FDD\u5B58\u6587\u7AE0\u7684\u65B9\u6CD5\uFF0C\u5B83\u9664\u4E86\u8981\u4FDD\u5B58\u6587\u7AE0\u672C\u8EAB\u4E4B\u5916\uFF0C\u8FD8\u8981\u4FDD\u5B58\u6587\u7AE0\u5BF9\u5E94\u7684\u6807\u7B7E\uFF0C\u6807\u7B7E\u548C\u6587\u7AE0\u4E0D\u5728\u540C\u4E00\u4E2A\u8868\u91CC\uFF0C\u4F46\u4F1A\u901A\u8FC7\u5728\u6587\u7AE0\u8868\u91CC\uFF08posts\uFF09\u4FDD\u5B58\u6807\u7B7E\u4E3B\u952E\uFF08tag_id\uFF09\u6765\u5173\u8054\u6807\u7B7E\u8868\uFF08tags\uFF09\uFF1A

public void savePosts(PostsParam postsParam) {
  // \u4FDD\u5B58\u6587\u7AE0
  save(posts);
  // \u5904\u7406\u6807\u7B7E
  insertOrUpdateTag(postsParam, posts);
}

\u90A3\u4E48\u6B64\u65F6\u5C31\u9700\u8981\u5F00\u542F\u4E8B\u52A1\uFF0C\u4FDD\u8BC1\u6587\u7AE0\u8868\u548C\u6807\u7B7E\u8868\u4E2D\u7684\u6570\u636E\u4FDD\u6301\u540C\u6B65\uFF0C\u8981\u4E48\u90FD\u6267\u884C\uFF0C\u8981\u4E48\u90FD\u4E0D\u6267\u884C\u3002

\u5426\u5219\u5C31\u6709\u53EF\u80FD\u9020\u6210\uFF0C\u6587\u7AE0\u4FDD\u5B58\u6210\u529F\u4E86\uFF0C\u4F46\u6807\u7B7E\u4FDD\u5B58\u5931\u8D25\u4E86\uFF0C\u6216\u8005\u6587\u7AE0\u4FDD\u5B58\u5931\u8D25\u4E86\uFF0C\u6807\u7B7E\u4FDD\u5B58\u6210\u529F\u4E86\u2014\u2014\u8FD9\u4E9B\u573A\u666F\u90FD\u4E0D\u7B26\u5408\u6211\u4EEC\u7684\u9884\u671F\u3002

\u4E3A\u4E86\u4FDD\u8BC1\u4E8B\u52A1\u662F\u6B63\u786E\u53EF\u9760\u7684\uFF0C\u5728\u6570\u636E\u5E93\u8FDB\u884C\u5199\u5165\u6216\u8005\u66F4\u65B0\u64CD\u4F5C\u65F6\uFF0C\u5C31\u5FC5\u987B\u5F97\u8868\u73B0\u51FA ACID \u7684 4 \u4E2A\u91CD\u8981\u7279\u6027\uFF1A

\u5176\u4E2D\uFF0C\u4E8B\u52A1\u9694\u79BB\u53C8\u5206\u4E3A 4 \u79CD\u4E0D\u540C\u7684\u7EA7\u522B\uFF0C\u5305\u62EC\uFF1A

\u9700\u8981\u683C\u5916\u6CE8\u610F\u7684\u662F\uFF1A\u4E8B\u52A1\u80FD\u5426\u751F\u6548\uFF0C\u53D6\u51B3\u4E8E\u6570\u636E\u5E93\u5F15\u64CE\u662F\u5426\u652F\u6301\u4E8B\u52A1\uFF0CMySQL \u7684 InnoDB \u5F15\u64CE\u662F\u652F\u6301\u4E8B\u52A1\u7684\uFF0C\u4F46 MyISAM \u5C31\u4E0D\u652F\u6301\u3002

\u5173\u4E8E Spring \u5BF9\u4E8B\u52A1\u7684\u652F\u6301

Spring \u652F\u6301\u4E24\u79CD\u4E8B\u52A1\u65B9\u5F0F\uFF0C\u5206\u522B\u662F\u7F16\u7A0B\u5F0F\u4E8B\u52A1\u548C\u58F0\u660E\u5F0F\u4E8B\u52A1\uFF0C\u540E\u8005\u6700\u5E38\u89C1\uFF0C\u901A\u5E38\u60C5\u51B5\u4E0B\u53EA\u9700\u8981\u4E00\u4E2A @Transactional \u5C31\u641E\u5B9A\u4E86\uFF08\u4EE3\u7801\u4FB5\u5165\u6027\u964D\u5230\u4E86\u6700\u4F4E\uFF09\uFF0C\u5C31\u50CF\u8FD9\u6837\uFF1A

@Transactional
public void savePosts(PostsParam postsParam) {
  // \u4FDD\u5B58\u6587\u7AE0
  save(posts);
  // \u5904\u7406\u6807\u7B7E
  insertOrUpdateTag(postsParam, posts);
}

1\uFF09\u7F16\u7A0B\u5F0F\u4E8B\u52A1

\u7F16\u7A0B\u5F0F\u4E8B\u52A1\u662F\u6307\u5C06\u4E8B\u52A1\u7BA1\u7406\u4EE3\u7801\u5D4C\u5165\u5D4C\u5165\u5230\u4E1A\u52A1\u4EE3\u7801\u4E2D\uFF0C\u6765\u63A7\u5236\u4E8B\u52A1\u7684\u63D0\u4EA4\u548C\u56DE\u6EDA\u3002

\u4F60\u6BD4\u5982\u8BF4\uFF0C\u4F7F\u7528 TransactionTemplate \u6765\u7BA1\u7406\u4E8B\u52A1\uFF1A

@Autowired
private TransactionTemplate transactionTemplate;
public void testTransaction() {

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {

                try {

                    // ....  \u4E1A\u52A1\u4EE3\u7801
                } catch (Exception e){
                    //\u56DE\u6EDA
                    transactionStatus.setRollbackOnly();
                }

            }
        });
}

\u518D\u6BD4\u5982\u8BF4\uFF0C\u4F7F\u7528 TransactionManager \u6765\u7BA1\u7406\u4E8B\u52A1\uFF1A

@Autowired
private PlatformTransactionManager transactionManager;

public void testTransaction() {

  TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
          try {
               // ....  \u4E1A\u52A1\u4EE3\u7801
              transactionManager.commit(status);
          } catch (Exception e) {
              transactionManager.rollback(status);
          }
}

\u5C31\u7F16\u7A0B\u5F0F\u4E8B\u52A1\u7BA1\u7406\u800C\u8A00\uFF0CSpring \u66F4\u63A8\u8350\u4F7F\u7528 TransactionTemplate\u3002

\u5728\u7F16\u7A0B\u5F0F\u4E8B\u52A1\u4E2D\uFF0C\u5FC5\u987B\u5728\u6BCF\u4E2A\u4E1A\u52A1\u64CD\u4F5C\u4E2D\u5305\u542B\u989D\u5916\u7684\u4E8B\u52A1\u7BA1\u7406\u4EE3\u7801\uFF0C\u5C31\u5BFC\u81F4\u4EE3\u7801\u770B\u8D77\u6765\u975E\u5E38\u7684\u81C3\u80BF\uFF0C\u4F46\u5BF9\u7406\u89E3 Spring \u7684\u4E8B\u52A1\u7BA1\u7406\u6A21\u578B\u975E\u5E38\u6709\u5E2E\u52A9\u3002

2\uFF09\u58F0\u660E\u5F0F\u4E8B\u52A1

\u58F0\u660E\u5F0F\u4E8B\u52A1\u5C06\u4E8B\u52A1\u7BA1\u7406\u4EE3\u7801\u4ECE\u4E1A\u52A1\u65B9\u6CD5\u4E2D\u62BD\u79BB\u4E86\u51FA\u6765\uFF0C\u4EE5\u58F0\u660E\u5F0F\u7684\u65B9\u5F0F\u6765\u5B9E\u73B0\u4E8B\u52A1\u7BA1\u7406\uFF0C\u5BF9\u4E8E\u5F00\u53D1\u8005\u6765\u8BF4\uFF0C\u58F0\u660E\u5F0F\u4E8B\u52A1\u663E\u7136\u6BD4\u7F16\u7A0B\u5F0F\u4E8B\u52A1\u66F4\u6613\u7528\u3001\u66F4\u597D\u7528\u3002

`,24),r=a("\u5F53\u7136\u4E86\uFF0C\u8981\u60F3\u5B9E\u73B0\u4E8B\u52A1\u7BA1\u7406\u548C\u4E1A\u52A1\u4EE3\u7801\u7684\u62BD\u79BB\uFF0C\u5C31\u5FC5\u987B\u5F97\u7528\u5230 Spring \u5F53\u4E2D\u6700\u5173\u952E\u6700\u6838\u5FC3\u7684\u6280\u672F\u4E4B\u4E00\uFF0C"),d={href:"https://tobebetterjavaer.com/springboot/aop-log.html",target:"_blank",rel:"noopener noreferrer"},k=a("AOP"),v=a("\uFF0C\u5176\u672C\u8D28\u662F\u5BF9\u65B9\u6CD5\u524D\u540E\u8FDB\u884C\u62E6\u622A\uFF0C\u7136\u540E\u5728\u76EE\u6807\u65B9\u6CD5\u5F00\u59CB\u4E4B\u524D\u521B\u5EFA\u6216\u8005\u52A0\u5165\u4E00\u4E2A\u4E8B\u52A1\uFF0C\u6267\u884C\u5B8C\u76EE\u6807\u65B9\u6CD5\u4E4B\u540E\u6839\u636E\u6267\u884C\u7684\u60C5\u51B5\u63D0\u4EA4\u6216\u8005\u56DE\u6EDA\u3002"),m=e(`

\u58F0\u660E\u5F0F\u4E8B\u52A1\u867D\u7136\u4F18\u4E8E\u7F16\u7A0B\u5F0F\u4E8B\u52A1\uFF0C\u4F46\u4E5F\u6709\u4E0D\u8DB3\uFF0C\u58F0\u660E\u5F0F\u4E8B\u52A1\u7BA1\u7406\u7684\u7C92\u5EA6\u662F\u65B9\u6CD5\u7EA7\u522B\uFF0C\u800C\u7F16\u7A0B\u5F0F\u4E8B\u52A1\u662F\u53EF\u4EE5\u7CBE\u786E\u5230\u4EE3\u7801\u5757\u7EA7\u522B\u7684\u3002

\u4E8B\u52A1\u7BA1\u7406\u6A21\u578B

Spring \u5C06\u4E8B\u52A1\u7BA1\u7406\u7684\u6838\u5FC3\u62BD\u8C61\u4E3A\u4E00\u4E2A\u4E8B\u52A1\u7BA1\u7406\u5668\uFF08TransactionManager\uFF09\uFF0C\u5B83\u7684\u6E90\u7801\u53EA\u6709\u4E00\u4E2A\u7B80\u5355\u7684\u63A5\u53E3\u5B9A\u4E49\uFF0C\u5C5E\u4E8E\u4E00\u4E2A\u6807\u8BB0\u63A5\u53E3\uFF1A

public interface TransactionManager {

}

\u8BE5\u63A5\u53E3\u6709\u4E24\u4E2A\u5B50\u63A5\u53E3\uFF0C\u5206\u522B\u662F\u7F16\u7A0B\u5F0F\u4E8B\u52A1\u63A5\u53E3 ReactiveTransactionManager \u548C\u58F0\u660E\u5F0F\u4E8B\u52A1\u63A5\u53E3 PlatformTransactionManager\u3002\u6211\u4EEC\u6765\u91CD\u70B9\u8BF4\u8BF4 PlatformTransactionManager\uFF0C\u8BE5\u63A5\u53E3\u5B9A\u4E49\u4E86 3 \u4E2A\u63A5\u53E3\u65B9\u6CD5\uFF1A

interface PlatformTransactionManager extends TransactionManager{
    // \u6839\u636E\u4E8B\u52A1\u5B9A\u4E49\u83B7\u53D6\u4E8B\u52A1\u72B6\u6001
    TransactionStatus getTransaction(TransactionDefinition definition)
            throws TransactionException;

    // \u63D0\u4EA4\u4E8B\u52A1
    void commit(TransactionStatus status) throws TransactionException;

    // \u4E8B\u52A1\u56DE\u6EDA
    void rollback(TransactionStatus status) throws TransactionException;
}

\u901A\u8FC7 PlatformTransactionManager \u8FD9\u4E2A\u63A5\u53E3\uFF0CSpring \u4E3A\u5404\u4E2A\u5E73\u53F0\u5982 JDBC(DataSourceTransactionManager)\u3001Hibernate(HibernateTransactionManager)\u3001JPA(JpaTransactionManager)\u7B49\u90FD\u63D0\u4F9B\u4E86\u5BF9\u5E94\u7684\u4E8B\u52A1\u7BA1\u7406\u5668\uFF0C\u4F46\u662F\u5177\u4F53\u7684\u5B9E\u73B0\u5C31\u662F\u5404\u4E2A\u5E73\u53F0\u81EA\u5DF1\u7684\u4E8B\u60C5\u4E86\u3002

\u53C2\u6570 TransactionDefinition \u548C @Transactional \u6CE8\u89E3\u662F\u5BF9\u5E94\u7684\uFF0C\u6BD4\u5982\u8BF4 @Transactional \u6CE8\u89E3\u4E2D\u5B9A\u4E49\u7684\u4E8B\u52A1\u4F20\u64AD\u884C\u4E3A\u3001\u9694\u79BB\u7EA7\u522B\u3001\u4E8B\u52A1\u8D85\u65F6\u65F6\u95F4\u3001\u4E8B\u52A1\u662F\u5426\u53EA\u8BFB\u7B49\u5C5E\u6027\uFF0C\u5728 TransactionDefinition \u90FD\u53EF\u4EE5\u627E\u5F97\u5230\u3002

\u8FD4\u56DE\u7C7B\u578B TransactionStatus \u4E3B\u8981\u7528\u6765\u5B58\u50A8\u5F53\u524D\u4E8B\u52A1\u7684\u4E00\u4E9B\u72B6\u6001\u548C\u6570\u636E\uFF0C\u6BD4\u5982\u8BF4\u4E8B\u52A1\u8D44\u6E90\uFF08connection\uFF09\u3001\u56DE\u6EDA\u72B6\u6001\u7B49\u3002

TransactionDefinition.java\uFF1A

public interface TransactionDefinition {

  // \u4E8B\u52A1\u7684\u4F20\u64AD\u884C\u4E3A
  default int getPropagationBehavior() {
    return PROPAGATION_REQUIRED;
  }

  // \u4E8B\u52A1\u7684\u9694\u79BB\u7EA7\u522B
  default int getIsolationLevel() {
    return ISOLATION_DEFAULT;
  }

  // \u4E8B\u52A1\u8D85\u65F6\u65F6\u95F4
  default int getTimeout() {
    return TIMEOUT_DEFAULT;
  }

  // \u4E8B\u52A1\u662F\u5426\u53EA\u8BFB
  default boolean isReadOnly() {
    return false;
  }
}

Transactional.java

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

  Propagation propagation() default Propagation.REQUIRED;
  Isolation isolation() default Isolation.DEFAULT;
  int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
  boolean readOnly() default false;

}

\u8BF4\u5230\u8FD9\uFF0C\u6211\u4EEC\u6765\u8BE6\u7EC6\u5730\u8BF4\u660E\u4E00\u4E0B Spring \u4E8B\u52A1\u7684\u4F20\u64AD\u884C\u4E3A\u3001\u4E8B\u52A1\u7684\u9694\u79BB\u7EA7\u522B\u3001\u4E8B\u52A1\u7684\u8D85\u65F6\u65F6\u95F4\u3001\u4E8B\u52A1\u7684\u53EA\u8BFB\u5C5E\u6027\uFF0C\u4EE5\u53CA\u4E8B\u52A1\u7684\u56DE\u6EDA\u89C4\u5219\u3002

\u4E8B\u52A1\u4F20\u64AD\u884C\u4E3A

\u5F53\u4E8B\u52A1\u65B9\u6CD5\u88AB\u53E6\u5916\u4E00\u4E2A\u4E8B\u52A1\u65B9\u6CD5\u8C03\u7528\u65F6\uFF0C\u5FC5\u987B\u6307\u5B9A\u4E8B\u52A1\u5E94\u8BE5\u5982\u4F55\u4F20\u64AD\uFF0C\u4F8B\u5982\uFF0C\u65B9\u6CD5\u53EF\u80FD\u7EE7\u7EED\u5728\u5F53\u524D\u4E8B\u52A1\u4E2D\u6267\u884C\uFF0C\u4E5F\u53EF\u4EE5\u5F00\u542F\u4E00\u4E2A\u65B0\u7684\u4E8B\u52A1\uFF0C\u5728\u81EA\u5DF1\u7684\u4E8B\u52A1\u4E2D\u6267\u884C\u3002

\u58F0\u660E\u5F0F\u4E8B\u52A1\u7684\u4F20\u64AD\u884C\u4E3A\u53EF\u4EE5\u901A\u8FC7 @Transactional \u6CE8\u89E3\u4E2D\u7684 propagation \u5C5E\u6027\u6765\u5B9A\u4E49\uFF0C\u6BD4\u5982\u8BF4\uFF1A

@Transactional(propagation = Propagation.REQUIRED)
public void savePosts(PostsParam postsParam) {
}

TransactionDefinition \u4E00\u5171\u5B9A\u4E49\u4E86 7 \u79CD\u4E8B\u52A1\u4F20\u64AD\u884C\u4E3A\uFF1A

01\u3001PROPAGATION_REQUIRED

\u8FD9\u4E5F\u662F @Transactional \u9ED8\u8BA4\u7684\u4E8B\u52A1\u4F20\u64AD\u884C\u4E3A\uFF0C\u6307\u7684\u662F\u5982\u679C\u5F53\u524D\u5B58\u5728\u4E8B\u52A1\uFF0C\u5219\u52A0\u5165\u8BE5\u4E8B\u52A1\uFF1B\u5982\u679C\u5F53\u524D\u6CA1\u6709\u4E8B\u52A1\uFF0C\u5219\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684\u4E8B\u52A1\u3002\u66F4\u786E\u5207\u5730\u610F\u601D\u662F\uFF1A

Class A {
    @Transactional(propagation=Propagation.PROPAGATION_REQUIRED)
    public void aMethod {
        //do something
        B b = new B();
        b.bMethod();
    }
}

Class B {
    @Transactional(propagation=Propagation.PROPAGATION_REQUIRED)
    public void bMethod {
       //do something
    }
}

\u8FD9\u4E2A\u4F20\u64AD\u884C\u4E3A\u4E5F\u6700\u597D\u7406\u89E3\uFF0CaMethod \u8C03\u7528\u4E86 bMethod\uFF0C\u53EA\u8981\u5176\u4E2D\u4E00\u4E2A\u65B9\u6CD5\u56DE\u6EDA\uFF0C\u6574\u4E2A\u4E8B\u52A1\u5747\u56DE\u6EDA\u3002

02\u3001PROPAGATION_REQUIRES_NEW

\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684\u4E8B\u52A1\uFF0C\u5982\u679C\u5F53\u524D\u5B58\u5728\u4E8B\u52A1\uFF0C\u5219\u628A\u5F53\u524D\u4E8B\u52A1\u6302\u8D77\u3002\u4E5F\u5C31\u662F\u8BF4\u4E0D\u7BA1\u5916\u90E8\u65B9\u6CD5\u662F\u5426\u5F00\u542F\u4E8B\u52A1\uFF0CPropagation.REQUIRES_NEW \u4FEE\u9970\u7684\u5185\u90E8\u65B9\u6CD5\u90FD\u4F1A\u5F00\u542F\u81EA\u5DF1\u7684\u4E8B\u52A1\uFF0C\u4E14\u5F00\u542F\u7684\u4E8B\u52A1\u4E0E\u5916\u90E8\u7684\u4E8B\u52A1\u76F8\u4E92\u72EC\u7ACB\uFF0C\u4E92\u4E0D\u5E72\u6270\u3002

Class A {
    @Transactional(propagation=Propagation.PROPAGATION_REQUIRED)
    public void aMethod {
        //do something
        B b = new B();
        b.bMethod();
    }
}

Class B {
    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void bMethod {
       //do something
    }
}

\u5982\u679C aMethod()\u53D1\u751F\u5F02\u5E38\u56DE\u6EDA\uFF0CbMethod()\u4E0D\u4F1A\u8DDF\u7740\u56DE\u6EDA\uFF0C\u56E0\u4E3A bMethod()\u5F00\u542F\u4E86\u72EC\u7ACB\u7684\u4E8B\u52A1\u3002\u4F46\u662F\uFF0C\u5982\u679C bMethod()\u629B\u51FA\u4E86\u672A\u88AB\u6355\u83B7\u7684\u5F02\u5E38\u5E76\u4E14\u8FD9\u4E2A\u5F02\u5E38\u6EE1\u8DB3\u4E8B\u52A1\u56DE\u6EDA\u89C4\u5219\u7684\u8BDD,aMethod()\u540C\u6837\u4E5F\u4F1A\u56DE\u6EDA\u3002

03\u3001PROPAGATION_NESTED

\u5982\u679C\u5F53\u524D\u5B58\u5728\u4E8B\u52A1\uFF0C\u5C31\u5728\u5F53\u524D\u4E8B\u52A1\u5185\u6267\u884C\uFF1B\u5426\u5219\uFF0C\u5C31\u6267\u884C\u4E0E PROPAGATION_REQUIRED \u7C7B\u4F3C\u7684\u64CD\u4F5C\u3002

04\u3001PROPAGATION_MANDATORY

\u5982\u679C\u5F53\u524D\u5B58\u5728\u4E8B\u52A1\uFF0C\u5219\u52A0\u5165\u8BE5\u4E8B\u52A1\uFF1B\u5982\u679C\u5F53\u524D\u6CA1\u6709\u4E8B\u52A1\uFF0C\u5219\u629B\u51FA\u5F02\u5E38\u3002

05\u3001PROPAGATION_SUPPORTS

\u5982\u679C\u5F53\u524D\u5B58\u5728\u4E8B\u52A1\uFF0C\u5219\u52A0\u5165\u8BE5\u4E8B\u52A1\uFF1B\u5982\u679C\u5F53\u524D\u6CA1\u6709\u4E8B\u52A1\uFF0C\u5219\u4EE5\u975E\u4E8B\u52A1\u7684\u65B9\u5F0F\u7EE7\u7EED\u8FD0\u884C\u3002

06\u3001PROPAGATION_NOT_SUPPORTED

\u4EE5\u975E\u4E8B\u52A1\u65B9\u5F0F\u8FD0\u884C\uFF0C\u5982\u679C\u5F53\u524D\u5B58\u5728\u4E8B\u52A1\uFF0C\u5219\u628A\u5F53\u524D\u4E8B\u52A1\u6302\u8D77\u3002

07\u3001PROPAGATION_NEVER

\u4EE5\u975E\u4E8B\u52A1\u65B9\u5F0F\u8FD0\u884C\uFF0C\u5982\u679C\u5F53\u524D\u5B58\u5728\u4E8B\u52A1\uFF0C\u5219\u629B\u51FA\u5F02\u5E38\u3002

3\u30014\u30015\u30016\u30017 \u8FD9 5 \u79CD\u4E8B\u52A1\u4F20\u64AD\u65B9\u5F0F\u4E0D\u5E38\u7528\uFF0C\u4E86\u89E3\u5373\u53EF\u3002

\u4E8B\u52A1\u9694\u79BB\u7EA7\u522B

\u524D\u9762\u6211\u4EEC\u5DF2\u7ECF\u4E86\u89E3\u4E86\u6570\u636E\u5E93\u7684\u4E8B\u52A1\u9694\u79BB\u7EA7\u522B\uFF0C\u518D\u6765\u7406\u89E3 Spring \u7684\u4E8B\u52A1\u9694\u79BB\u7EA7\u522B\u5C31\u5BB9\u6613\u591A\u4E86\u3002

TransactionDefinition \u4E2D\u4E00\u5171\u5B9A\u4E49\u4E86 5 \u79CD\u4E8B\u52A1\u9694\u79BB\u7EA7\u522B\uFF1A

\u901A\u5E38\u60C5\u51B5\u4E0B\uFF0C\u6211\u4EEC\u91C7\u7528\u9ED8\u8BA4\u7684\u9694\u79BB\u7EA7\u522B ISOLATION_DEFAULT \u5C31\u53EF\u4EE5\u4E86\uFF0C\u4E5F\u5C31\u662F\u4EA4\u7ED9\u6570\u636E\u5E93\u6765\u51B3\u5B9A\uFF0C\u53EF\u4EE5\u901A\u8FC7 SELECT @@transaction_isolation; \u547D\u4EE4\u6765\u67E5\u770B MySql \u7684\u9ED8\u8BA4\u9694\u79BB\u7EA7\u522B\uFF0C\u7ED3\u679C\u4E3A REPEATABLE-READ\uFF0C\u4E5F\u5C31\u662F\u53EF\u91CD\u590D\u8BFB\u3002

\u4E8B\u52A1\u7684\u8D85\u65F6\u65F6\u95F4

\u4E8B\u52A1\u8D85\u65F6\uFF0C\u4E5F\u5C31\u662F\u6307\u4E00\u4E2A\u4E8B\u52A1\u6240\u5141\u8BB8\u6267\u884C\u7684\u6700\u957F\u65F6\u95F4\uFF0C\u5982\u679C\u5728\u8D85\u65F6\u65F6\u95F4\u5185\u8FD8\u6CA1\u6709\u5B8C\u6210\u7684\u8BDD\uFF0C\u5C31\u81EA\u52A8\u56DE\u6EDA\u3002

\u5047\u5982\u4E8B\u52A1\u7684\u6267\u884C\u65F6\u95F4\u683C\u5916\u7684\u957F\uFF0C\u7531\u4E8E\u4E8B\u52A1\u6D89\u53CA\u5230\u5BF9\u6570\u636E\u5E93\u7684\u9501\u5B9A\uFF0C\u5C31\u4F1A\u5BFC\u81F4\u957F\u65F6\u95F4\u8FD0\u884C\u7684\u4E8B\u52A1\u5360\u7528\u6570\u636E\u5E93\u8D44\u6E90\u3002

\u4E8B\u52A1\u7684\u53EA\u8BFB\u5C5E\u6027

\u5982\u679C\u4E00\u4E2A\u4E8B\u52A1\u53EA\u662F\u5BF9\u6570\u636E\u5E93\u6267\u884C\u8BFB\u64CD\u4F5C\uFF0C\u90A3\u4E48\u8BE5\u6570\u636E\u5E93\u5C31\u53EF\u4EE5\u5229\u7528\u4E8B\u52A1\u7684\u53EA\u8BFB\u5C5E\u6027\uFF0C\u91C7\u53D6\u4F18\u5316\u63AA\u65BD\uFF0C\u9002\u7528\u4E8E\u591A\u6761\u6570\u636E\u5E93\u67E5\u8BE2\u64CD\u4F5C\u4E2D\u3002

\u4E3A\u4EC0\u4E48\u4E00\u4E2A\u67E5\u8BE2\u64CD\u4F5C\u8FD8\u8981\u542F\u7528\u4E8B\u52A1\u652F\u6301\u5462\uFF1F

\u8FD9\u662F\u56E0\u4E3A MySql\uFF08innodb\uFF09\u9ED8\u8BA4\u5BF9\u6BCF\u4E00\u4E2A\u8FDE\u63A5\u90FD\u542F\u7528\u4E86 autocommit \u6A21\u5F0F\uFF0C\u5728\u8BE5\u6A21\u5F0F\u4E0B\uFF0C\u6BCF\u4E00\u4E2A\u53D1\u9001\u5230 MySql \u670D\u52A1\u5668\u7684 SQL \u8BED\u53E5\u90FD\u4F1A\u5728\u4E00\u4E2A\u5355\u72EC\u7684\u4E8B\u52A1\u4E2D\u8FDB\u884C\u5904\u7406\uFF0C\u6267\u884C\u7ED3\u675F\u540E\u4F1A\u81EA\u52A8\u63D0\u4EA4\u4E8B\u52A1\u3002

\u90A3\u5982\u679C\u6211\u4EEC\u7ED9\u65B9\u6CD5\u52A0\u4E0A\u4E86 @Transactional \u6CE8\u89E3\uFF0C\u90A3\u8FD9\u4E2A\u65B9\u6CD5\u4E2D\u6240\u6709\u7684 SQL \u90FD\u4F1A\u653E\u5728\u4E00\u4E2A\u4E8B\u52A1\u91CC\u3002\u5426\u5219\uFF0C\u6BCF\u6761 SQL \u90FD\u4F1A\u5355\u72EC\u5F00\u542F\u4E00\u4E2A\u4E8B\u52A1\uFF0C\u4E2D\u95F4\u88AB\u5176\u4ED6\u4E8B\u52A1\u4FEE\u6539\u4E86\u6570\u636E\uFF0C\u90FD\u4F1A\u5B9E\u65F6\u8BFB\u53D6\u5230\u3002

\u6709\u4E9B\u60C5\u51B5\u4E0B\uFF0C\u5F53\u4E00\u6B21\u6267\u884C\u591A\u6761\u67E5\u8BE2\u8BED\u53E5\u65F6\uFF0C\u9700\u8981\u4FDD\u8BC1\u6570\u636E\u4E00\u81F4\u6027\u65F6\uFF0C\u5C31\u9700\u8981\u542F\u7528\u4E8B\u52A1\u652F\u6301\u3002\u5426\u5219\u4E0A\u4E00\u6761 SQL \u67E5\u8BE2\u540E\uFF0C\u88AB\u5176\u4ED6\u7528\u6237\u6539\u53D8\u4E86\u6570\u636E\uFF0C\u90A3\u4E48\u4E0B\u4E00\u4E2A SQL \u67E5\u8BE2\u53EF\u80FD\u5C31\u4F1A\u51FA\u73B0\u4E0D\u4E00\u81F4\u7684\u72B6\u6001\u3002

\u4E8B\u52A1\u7684\u56DE\u6EDA\u7B56\u7565

\u9ED8\u8BA4\u60C5\u51B5\u4E0B\uFF0C\u4E8B\u52A1\u53EA\u5728\u51FA\u73B0\u8FD0\u884C\u65F6\u5F02\u5E38\uFF08Runtime Exception\uFF09\u65F6\u56DE\u6EDA\uFF0C\u4EE5\u53CA Error\uFF0C\u51FA\u73B0\u68C0\u67E5\u5F02\u5E38\uFF08checked exception\uFF0C\u9700\u8981\u4E3B\u52A8\u6355\u83B7\u5904\u7406\u6216\u8005\u5411\u4E0A\u629B\u51FA\uFF09\u65F6\u4E0D\u56DE\u6EDA\u3002

`,57),b={href:"https://tobebetterjavaer.com/exception/gailan.html#%E4%B8%89%E3%80%81checked%E5%92%8Cunchecked%E5%BC%82%E5%B8%B8",target:"_blank",rel:"noopener noreferrer"},h=a("checked\u548Cunchecked\u5F02\u5E38"),g=e(`

\u5982\u679C\u4F60\u60F3\u8981\u56DE\u6EDA\u7279\u5B9A\u7684\u5F02\u5E38\u7C7B\u578B\u7684\u8BDD\uFF0C\u53EF\u4EE5\u8FD9\u6837\u8BBE\u7F6E\uFF1A

@Transactional(rollbackFor= MyException.class)

\u5173\u4E8E Spring Boot \u5BF9\u4E8B\u52A1\u7684\u652F\u6301

\u4EE5\u524D\uFF0C\u6211\u4EEC\u9700\u8981\u901A\u8FC7 XML \u914D\u7F6E Spring \u6765\u6258\u7BA1\u4E8B\u52A1\uFF0C\u6709\u4E86 Spring Boot \u4E4B\u540E\uFF0C\u4E00\u5207\u5C31\u53D8\u5F97\u66F4\u52A0\u7B80\u5355\u4E86\uFF0C\u53EA\u9700\u8981\u5728\u4E1A\u52A1\u5C42\u6DFB\u52A0\u4E8B\u52A1\u6CE8\u89E3\uFF08@Transactional\uFF09\u5C31\u53EF\u4EE5\u5FEB\u901F\u5F00\u542F\u4E8B\u52A1\u3002

\u4E5F\u5C31\u662F\u8BF4\uFF0C\u6211\u4EEC\u53EA\u9700\u8981\u628A\u7126\u70B9\u653E\u5728 @Transactional \u6CE8\u89E3\u4E0A\u5C31\u53EF\u4EE5\u4E86\u3002

@Transactional \u7684\u4F5C\u7528\u8303\u56F4

@Transactional \u7684\u5E38\u7528\u914D\u7F6E\u53C2\u6570

\u867D\u7136 @Transactional \u6CE8\u89E3\u6E90\u7801\u4E2D\u5B9A\u4E49\u4E86\u5F88\u591A\u5C5E\u6027\uFF0C\u4F46\u5927\u591A\u6570\u65F6\u5019\uFF0C\u6211\u90FD\u662F\u91C7\u7528\u9ED8\u8BA4\u914D\u7F6E\uFF0C\u5F53\u7136\u4E86\uFF0C\u5982\u679C\u9700\u8981\u81EA\u5B9A\u4E49\u7684\u8BDD\uFF0C\u524D\u9762\u4E5F\u90FD\u8BF4\u660E\u8FC7\u4E86\u3002

@Transactional \u7684\u4F7F\u7528\u6CE8\u610F\u4E8B\u9879\u603B\u7ED3

1\uFF09\u8981\u5728 public \u65B9\u6CD5\u4E0A\u4F7F\u7528\uFF0C\u5728AbstractFallbackTransactionAttributeSource\u7C7B\u7684computeTransactionAttribute\u65B9\u6CD5\u4E2D\u6709\u4E2A\u5224\u65AD\uFF0C\u5982\u679C\u76EE\u6807\u65B9\u6CD5\u4E0D\u662Fpublic\uFF0C\u5219TransactionAttribute\u8FD4\u56DEnull\uFF0C\u5373\u4E0D\u652F\u6301\u4E8B\u52A1\u3002

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    // Don't allow no-public methods as required.
    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
      return null;
    }

    // The method may be on an interface, but we need attributes from the target class.
    // If the target class is null, the method will be unchanged.
    Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

    // First try is the method in the target class.
    TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
    if (txAttr != null) {
      return txAttr;
    }

    // Second try is the transaction attribute on the target class.
    txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
    if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
      return txAttr;
    }

    if (specificMethod != method) {
      // Fallback is to look at the original method.
      txAttr = findTransactionAttribute(method);
      if (txAttr != null) {
        return txAttr;
      }
      // Last fallback is the class of the original method.
      txAttr = findTransactionAttribute(method.getDeclaringClass());
      if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
        return txAttr;
      }
    }
    return null;
  }

2\uFF09\u907F\u514D\u540C\u4E00\u4E2A\u7C7B\u4E2D\u8C03\u7528 @Transactional \u6CE8\u89E3\u7684\u65B9\u6CD5\uFF0C\u8FD9\u6837\u4F1A\u5BFC\u81F4\u4E8B\u52A1\u5931\u6548\u3002

\u66F4\u591A\u4E8B\u52A1\u5931\u6548\u7684\u573A\u666F\u53EF\u4EE5\u53C2\u8003\uFF1A

`,14),T={href:"https://mp.weixin.qq.com/s/qoWlR4ohVMfZf8IlhdSQDQ",target:"_blank",rel:"noopener noreferrer"},f=a("https://mp.weixin.qq.com/s/qoWlR4ohVMfZf8IlhdSQDQ"),y=e(`

\u6D4B\u8BD5\u4E8B\u52A1\u662F\u5426\u8D77\u6548

\u5728\u6D4B\u8BD5\u4E4B\u524D\uFF0C\u6211\u4EEC\u5148\u628A Spring Boot \u9ED8\u8BA4\u7684\u65E5\u5FD7\u7EA7\u522B info \u8C03\u6574\u4E3A debug\uFF0C\u5728 application.yml \u6587\u4EF6\u4E2D \u4FEE\u6539\uFF1A

logging:
  level:
    org:
      hibernate: debug
      springframework:
        web: debug

\u7136\u540E\uFF0C\u6765\u770B\u4FEE\u6539\u4E4B\u524D\u67E5\u5230\u7684\u6570\u636E\uFF1A

\u5F00\u641E\u3002\u5728\u63A7\u5236\u5668\u4E2D\u6DFB\u52A0\u4E00\u4E2A update \u63A5\u53E3\uFF0C\u51C6\u5907\u4FEE\u6539\u6570\u636E\uFF0C\u6253\u7B97\u628A\u6C89\u9ED8\u738B\u4E8C\u7684\u72D7\u817F\u5B50\u4FEE\u6539\u4E3A\u6C89\u9ED8\u738B\u4E8C\u7684\u72D7\u817F\uFF1A


`,7),_=a("\u66F4\u591A\u5185\u5BB9\uFF0C\u53EA\u9488\u5BF9\u300AJava \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF\u300B\u661F\u7403\u7528\u6237\u5F00\u653E\uFF0C\u9700\u8981\u7684\u5C0F\u4F19\u4F34\u53EF\u4EE5"),w={href:"https://tobebetterjavaer.com/zhishixingqiu/",target:"_blank",rel:"noopener noreferrer"},E=a("\u6233\u94FE\u63A5\u{1F517}"),A=a("\u52A0\u5165\u6211\u4EEC\u7684\u661F\u7403\uFF0C\u4E00\u8D77\u5B66\u4E60\uFF0C\u4E00\u8D77\u5377\u3002\u3002"),R=n("strong",null,"\u7F16\u7A0B\u55B5",-1),P=a("\u{1F431}\u662F\u4E00\u4E2A Spring Boot+Vue \u7684\u524D\u540E\u7AEF\u5206\u79BB\u9879\u76EE\uFF0C\u878D\u5408\u4E86\u5E02\u9762\u4E0A\u7EDD\u5927\u591A\u6570\u6D41\u884C\u7684\u6280\u672F\u8981\u70B9\u3002\u901A\u8FC7\u5B66\u4E60\u5B9E\u6218\u9879\u76EE\uFF0C\u4F60\u53EF\u4EE5\u5C06\u6240\u5B66\u7684\u77E5\u8BC6\u901A\u8FC7\u5B9E\u8DF5\u8FDB\u884C\u68C0\u9A8C\u3001\u4F60\u53EF\u4EE5\u62D3\u5BBD\u81EA\u5DF1\u7684\u6280\u672F\u8FB9\u754C\uFF0C\u4F60\u53EF\u4EE5\u638C\u63E1\u4E00\u4E2A\u771F\u6B63\u7684\u5B9E\u6218\u9879\u76EE\u662F\u5982\u4F55\u4ECE 0 \u5230 1 \u7684\u3002"),I=n("hr",null,null,-1),M=a("\u7F16\u7A0B\u55B5\uFF1A"),x={href:"https://github.com/itwanger/coding-more",target:"_blank",rel:"noopener noreferrer"},O=a("https://github.com/itwanger/coding-more"),D=a("\u672C\u9879\u76EE\u6E90\u7801\uFF1A"),S={href:"https://github.com/itwanger/codingmore-learning/tree/main/codingmore-transactional",target:"_blank",rel:"noopener noreferrer"},j=a("https://github.com/itwanger/codingmore-learning"),U=n("p",null,[n("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png",alt:""})],-1);function L(N,Q){const s=o("ExternalLinkIcon");return i(),c("div",null,[u,n("p",null,[r,n("a",d,[k,t(s)]),v]),m,n("p",null,[n("a",b,[h,t(s)])]),g,n("blockquote",null,[n("p",null,[n("a",T,[f,t(s)])])]),y,n("p",null,[_,n("a",w,[E,t(s)]),A,R,P]),I,n("blockquote",null,[n("ul",null,[n("li",null,[M,n("a",x,[O,t(s)])]),n("li",null,[D,n("a",S,[j,t(s)])])])]),U])}var q=p(l,[["render",L],["__file","transaction.html.vue"]]);export{q as default};