• 译 4. 事务管理


    1. 打开我们的STS, New————> Import Spring Getting Started Content

    2. 输入ma ,选择Managing Transactions

    3. 创建一个booking Service

    首先,使用BookingService类创建一个基于JDBC的服务,将人员按名称登录到系统中。

    src/main/java/hello/BookingService.java

    package hello;
    
    import java.util.List;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Component;
    import org.springframework.transaction.annotation.Transactional;
    
    @Component
    public class BookingService {
    
        private final static Logger logger = LoggerFactory.getLogger(BookingService.class);
    
        private final JdbcTemplate jdbcTemplate;
    
        public BookingService(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
    
        @Transactional
        public void book(String... persons) {
            for (String person : persons) {
                logger.info("Booking " + person + " in a seat...");
                jdbcTemplate.update("insert into BOOKINGS(FIRST_NAME) values (?)", person);
            }
        }
    
        public List<String> findAllBookings() {
            return jdbcTemplate.query("select FIRST_NAME from BOOKINGS",
                    (rs, rowNum) -> rs.getString("FIRST_NAME"));
        }
    
    }
     该代码有一个自动装配的JdbcTemplate,这是一个方便的模板类,用于执行下面代码所需的所有数据库交互。

    你也有一个预订方法,旨在预订多个人。 它循环遍历人员列表,并且使用JdbcTemplate将它们插入到BOOKINGS表中。 此方法使用@Transactional进行标记,这意味着任何失败都会导致整个操作回滚到之前的状态,并重新抛出原始异常。 这意味着如果一个人未能被添加,则没有人会被添加到预订中。

    您还有一个findAllBookings方法来查询数据库。 从数据库中提取的每一行都被转换为一个字符串,然后组合成一个List。

    构建一个应用程序

    src/main/java/hello/Application.java

    package hello;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }

    @SpringBootApplication是一个方便的注解,它增加了以下所有内容:

    • @Configuration将类标记为应用程序上下文的bean定义的来源。
    • @EnableAutoConfiguration通知Spring Boot根据类路径设置,其他bean和各种属性设置开始添加bean。
    • 通常你会为Spring MVC应用程序添加@EnableWebMvc,但Spring Boot在类路径中看到spring-webmvc时会自动添加。 这将该应用程序标记为Web应用程序并激活关键行为,例如设置DispatcherServlet。
    • @ComponentScan告诉Spring在hello包中查找其他组件,配置和服务,以便找到控制器。

    main()方法使用Spring Boot的SpringApplication.run()方法启动应用程序。 你有没有注意到没有一行XML? 没有web.xml文件。 这个Web应用程序是100%纯Java,您不必处理配置任何管道或基础设施。

    您的应用程序实际上是零配置。 Spring Boot会检测类路径和h2上的spring-jdbc,并自动为您创建一个DataSource和一个JdbcTemplate。 由于这样的基础架构现在可用并且没有专门的配置,因此还会为您创建一个DataSourceTransactionManager:这是拦截@Transactional批注方法(例如BookingService上的书)的组件。 BookingService通过类路径扫描进行检测。

    本指南中演示的另一个Spring Boot功能是在启动时初始化模式的能力

    src/main/resources/schema.sql

    drop table BOOKINGS if exists;
    create table BOOKINGS(ID serial, FIRST_NAME varchar(5) NOT NULL);

    还有一个CommandLineRunner注入BookingService并展示各种事务用例。

    src/main/java/hello/AppRunner.java

    package hello;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.stereotype.Component;
    import org.springframework.util.Assert;
    
    @Component
    class AppRunner implements CommandLineRunner {
    
        private final static Logger logger = LoggerFactory.getLogger(AppRunner.class);
    
        private final BookingService bookingService;
    
        public AppRunner(BookingService bookingService) {
            this.bookingService = bookingService;
        }
    
        @Override
        public void run(String... args) throws Exception {
            bookingService.book("Alice", "Bob", "Carol");
            Assert.isTrue(bookingService.findAllBookings().size() == 3,
                    "First booking should work with no problem");
            logger.info("Alice, Bob and Carol have been booked");
            try {
                bookingService.book("Chris", "Samuel");
            } catch (RuntimeException e) {
                logger.info("v--- The following exception is expect because 'Samuel' is too " +
                        "big for the DB ---v");
                logger.error(e.getMessage());
            }
    
            for (String person : bookingService.findAllBookings()) {
                logger.info("So far, " + person + " is booked.");
            }
            logger.info("You shouldn't see Chris or Samuel. Samuel violated DB constraints, " +
                    "and Chris was rolled back in the same TX");
            Assert.isTrue(bookingService.findAllBookings().size() == 3,
                    "'Samuel' should have triggered a rollback");
    
            try {
                bookingService.book("Buddy", null);
            } catch (RuntimeException e) {
                logger.info("v--- The following exception is expect because null is not " +
                        "valid for the DB ---v");
                logger.error(e.getMessage());
            }
    
            for (String person : bookingService.findAllBookings()) {
                logger.info("So far, " + person + " is booked.");
            }
            logger.info("You shouldn't see Buddy or null. null violated DB constraints, and " +
                    "Buddy was rolled back in the same TX");
            Assert.isTrue(bookingService.findAllBookings().size() == 3,
                    "'null' should have triggered a rollback");
        }
    }

    您可以使用Gradle或Maven从命令行运行应用程序。 或者您可以构建一个包含所有必需的依赖项,类和资源的可执行JAR文件,并运行该文件。 这使得在整个开发生命周期内跨越不同环境等,将服务作为应用程序发布,版本化和部署变得非常容易。

    我们通过STS生成可执行Jar

    生成后可以看到这个文件在target文件夹下

    如果您正在使用Gradle,则可以使用./gradlew bootRun运行该应用程序。 或者您可以使用./gradlew构建构建JAR文件。 然后你可以运行JAR文件:

    java -jar build/libs/gs-managing-transactions-0.1.0.jar

    如果您使用的是Maven,则可以使用./mvnw spring-boot:run来运行该应用程序。 或者,您可以使用./mvnw clean包构建JAR文件。 然后你可以运行JAR文件:

    java -jar target/gs-managing-transactions-0.1.0.jar

    执行后可以看到回显

    BOOKINGS表在first_name列上有两个约束:

    名称不能超过五个字符。

    名称不能为空。

    前三个名字是爱丽丝,鲍勃和卡罗尔。 该申请声称有三人被添加到该表中。 如果这样做没有成功,申请就会提前退出。

    接下来,另一个预订是为克里斯和塞缪尔完成的。 塞缪尔的名字故意太长,强制插入错误。 交易行为规定克里斯和塞缪尔; 也就是这个事务,应该被回滚。 因此,该表中应该只有三个人,这一说法表明了这一点。

    最后,Buddy和null都被预订了。 如输出所示,null也会导致回滚,从而留下相同的三个人。


     源码:点击查看

     恭喜! 您刚刚使用Spring开发了一个包含非侵入事务的简单JDBC应用程序。

  • 相关阅读:
    JDK1.5新特性,基础类库篇,调用外部命令类(ProcessBuilder)用法
    JDK1.5新特性,基础类库篇,格式化类(Formatter)用法
    JDK1.5新特性,语言篇
    几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)
    JSON概述及其在JavaScript与Java中的应用(整理)
    JavaScript:表单常用验证脚本(整理)
    JavaScript:零星知识
    浏览器脚本概述(整理)
    Angular
    Angular
  • 原文地址:https://www.cnblogs.com/xingyunblog/p/9106034.html
Copyright © 2020-2023  润新知