1. 打开咱们的STS, New————> Import Spring Getting Started Contenthtml
2. 输入ma ,选择Managing Transactionsjava
3. 建立一个booking Servicegit
首先,使用BookingService类建立一个基于JDBC的服务,将人员按名称登陆到系统中。github
src/main/java/hello/BookingService.javaweb
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将它们插入到BOOKINGS表中。 此方法使用@Transactional进行标记,这意味着任何失败都会致使整个操做回滚到以前的状态,并从新抛出原始异常。 这意味着若是一我的未能被添加,则没有人会被添加到预订中。spring
您还有一个findAllBookings方法来查询数据库。 从数据库中提取的每一行都被转换为一个字符串,而后组合成一个List。sql
构建一个应用程序数据库
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是一个方便的注解,它增长了如下全部内容:mvc
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应用程序。