详解在Spring Boot中使用数据库事务

网友投稿 252 2023-05-14


详解在Spring Boot中使用数据库事务

我们在前面已经分别介绍了如何在spring Boot中使用JPA以及如何在Spring Boot中输出REST资源。那么关于数据库访问还有一个核心操作那就是事务的处理了,前面两篇博客小伙伴们已经见识到Spring Boot带给我们的巨大便利了,其实不用猜,我们也知道Spring Boot在数据库事务处理问题上也给我们带来惊喜,OK,废话不多说,就来看看如何在Spring Boot中使用事务吧。

OK,那我们开始今天愉快的coding旅程吧!

创建Project并添加数据库依赖

这个没啥好说的,不懂如何创建一个Spring Boot工程的小伙伴请移步这里初识Spring Boot框架。创建的时候选择依赖时选择Web和JPA,如下图:

OK,工程创建成功之后接下来我们来添加数据库驱动,和前文一样,我这里还是以mysql数据库为例,在pom.xml文件中添加如下依赖:

mysql

mysql-connector-java

5.1.40

配置application.properties

配置方式还是和前文一模一样,我这里直接贴代码,含义不再赘述:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/rest

spring.datasource.username=root

spring.datasource.password=sang

spring.jpa.hibernate.ddl-auto=update

spring.jpa.show-sql=true

spring.jackson.serialization.indent_output=true

创建实体类

实体类还是一个Person,如下:

@Entity

public class Person {

@Id

@GeneratedValue

private Long id;

private String name;

private String address;

private Integer age;

public Person() {

}

public Long getId() {

return id;

}

public void setId(Long id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public Person(Long id, String name, String address, Integer age) {

this.id = id;

this.name = name;

this.address = address;

this.age = age;

}

}

创建实体类的Repository

public interface PersonRepository extends JpaRepository {

}

这里因为我们的目的是测试事务,所以Repository中暂时先不写任何东西。

创建业务服务Service

创建Service接口

public interface DemoService {

public Person savePersonWithRollBack(Person person);

public Person savePersonWithoutRollBack(Person person);

}

创建Service实现类

@Service

public class DemoServiceImpl implements DemoService {

@Autowired

PersonRepository personRepository;

@Transactional(rollbackFor = {IllegalArgumentException.class})

@Override

public Person savePersonWithRollBack(Person person) {

Person p = personRepository.save(person);

if (person.getName().equals("sang")) {

throw new IllegalArgumentException("sang 已存在,数据将回滚");

}

return p;

}

@Transactional(noRollbackFor = {IllegalArgumentException.class})

@Override

public Person savePersonWithoutRollBack(Person person) {

Person p = personRepository.save(person);

if (person.getName().equals("sang")) {

throw new IllegalArgumentException("sang已存在,但数据不会回滚");

}

return p;

}

}

在这里我们使用到了@Transactional注解,该注解中有一个rollbackFor属性,该属性的值为数组,表示当该方法中抛出指定的异常时数据回滚,该注解还有个属性叫noRollbackFor,表示当该方法中抛出指定的异常时数据不回滚,这两个属性我们分别在两个方法中体现。

创建控制器

@RestController

public class MyController {

@Autowired

private DemoService demoService;

@RequestMapping("/norollback")

public Person noRollback(Person person) {

return demoService.savePersonWithoutRollBack(person);

}

@RequestMapping("/rollback")

public Person rollback(Person person) {

return demoService.savePersonWithRollBack(person);

}

}

控制器创建成功之后接下来我们就可以直接在浏览器中访问这两个地址看看效果了。

测试

首先在浏览器中输入http://localhost:8080/rollback?name=sang&age=100,我们来测试回滚的情况,访问结果如下:

看看控制台抛出的异常:

这个时候再去查看数据库,发现数据表中并没有插入数据。

再在地址栏输入http://localhost:8080/norollback?name=sang&age=100,测试结果如下:

浏览器依然报错:

控制台也打印了错误,但是这个时候再去看数据库,数据已成功插入了。如下图:

OK,以上就是数据库事务在Spring Boot中的简单使用。

本文案例github地址https://github.com/lenve/JauEQPiThWjvaEETest/tree/master/Test24-Transaction。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:详解在Spring Boot中使用JPA
下一篇:详解如何在Angular中快速定位DOM元素
相关文章

 发表评论

暂时没有评论,来抢沙发吧~