zoukankan      html  css  js  c++  java
  • SpringBoot与事务控制@Transactional(详细)

    众所周知,保证数据库一致性的操作,就是事务的控制。而Spring事务管理可以分为两种:编程式(编写代码即xml配置文件)以及声明式(通过切面编程即AOP注入)(具体配置可见博客)。

    对于SpringBoot,推荐操作是,使用@Transactional注解来申明事务(@Transactional注解详情可见博客https://www.cnblogs.com/pengpengdeyuan/p/12737891.html)。

    下面一起使用@Transactional来添加事务控制。

    1、导包

    要在Spring boot中支持事务,首先要导入Spring boot提供的JDBC或JPA依赖:

    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-jdbc</artifactId>
       <scope>test</scope>
    </dependency>
     
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-jpa</artifactId>
       <scope>test</scope>
    </dependency>

    当我们导入这两个包后,SpringBoot会自动默认注入DataSourceTransactionManager或JpaTransactionManager。

    2、在启动类上添加@EnableTransactionManagement注解

    由于SpringBoot会自动配置事务,所以这个注解可加也不加,具体实现可在org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration类中查看。

    @SpringBootApplication
    //启用事务管理(可省略)
    @EnableTransactionManagement
    @MapperScan("mapper路径")
    public class KxlApplication {
        public static void main(String[] args) {
            SpringApplication.run(KxlApplication.class, args);
        }
    }

    三、在service层添加@Transactional注解

    @Transactional注解可加在类上,也可加在方法上。

    若你写代码的风格规范的话,一般@Transactional加在Service层。

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Scope;
    import org.springframework.context.annotation.ScopedProxyMode;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Isolation;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    @Service
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
    public class TestService implements ITestService {
        @Autowired
        private TestMapper testMapper;
    
    }
    @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS),该注解的作用是表明此类上所有方法上的事务都是CGLib方式代理的。
    具体可详见博客https://www.cnblogs.com/pengpengdeyuan/p/12737585.html

    以上配置本人运行未报错,但有些小伙伴在启动项目时可能会遇到类似以下报错,
    Description:
    
    The bean 'testService' could not be injected as a 'com.pk.kxl.service.impl.TestService' because it is a JDK dynamic proxy that implements:
        com.pk.kxl.service.ITestService
    
    
    Action:
    
    Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.

    这个原因是由jdk自动代理与CGlib代理两种代理方式的区别造成的,如有发现可以完全按照我的配置,也可参考博客https://www.cnblogs.com/pengpengdeyuan/p/12737585.html

  • 相关阅读:
    动手动脑3
    动手动脑2
    编写一个文件分割工具,能把一个大文件分割成多个小的文件。并且能再次把他们合并起来得到完整的文件
    编写一个文件加解密程序通过命令行完成加解密工作
    编写一个程序指定一个文件夹,能自动计算出其总容量
    Java中常见的异常处理汇总
    覆盖 动手动脑
    课堂代码验证
    如何在静态方法中访问类的实例成员 及查询“你已经创建了多少个对象”
    Java的字段初始化规律
  • 原文地址:https://www.cnblogs.com/pengpengdeyuan/p/12736799.html
Copyright © 2011-2022 走看看