天天看点

Spring boot 整合 jdbcTemplate & 事务 三

pom.xml 文件引入

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
   </dependency>
           

在resources 文件配置 application.properties

Spring boot 整合 jdbcTemplate &amp; 事务 三
spring.datasource.url=jdbc:mysql://hadoop03.fandong.com:3306/springStudy
spring.datasource.username=nodejs1
spring.datasource.password=nodejs1
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
           

进行数据的连接配置。

定义服务接口

package com.fandong.it.weapon.service;

public interface UserService {
   void update(String name, Integer age);
}
           

实现服务接口

package com.fandong.it.weapon.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void update(String name, Integer age) {
       String sql = "INSERT INTO user (name, age ) VALUES ( ? , ?)";
       jdbcTemplate.update(sql,name,age);
    }
}
           

controller 进行使用?

package com.fandong.it.weapon.Controller;

import com.fandong.it.weapon.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

    @Autowired
    private UserService userService;

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "hello,spring boot";
    }

    @ResponseBody
    @RequestMapping("/add")
    public String addUser(){
        userService.update("haha",29);
        return "success";
    }
}
           

调用使用:

Spring boot 整合 jdbcTemplate &amp; 事务 三

查看数据库:

Spring boot 整合 jdbcTemplate &amp; 事务 三

添加事务:

@Transactional

@ResponseBody
    @RequestMapping("/add")
    @Transactional
    public String addUser(){
        userService.update("hah1a",39);
        int c = 1/ 0;
        return "success";
    }
           

在类上直接添加。

Spring boot 整合 jdbcTemplate &amp; 事务 三

发现执行到了 异常代码处。

查看数据库事务是否成功?

Spring boot 整合 jdbcTemplate &amp; 事务 三

说明事务添加成功。

spring  事务有7 中类型

REQUIRED(0),
    SUPPORTS(1),
    MANDATORY(2),
    REQUIRES_NEW(3),
    NOT_SUPPORTED(4),
    NEVER(5),
    NESTED(6);
           
/**
	 * Support a current transaction, create a new one if none exists.
	 * Analogous to EJB transaction attribute of the same name.
	 * <p>This is the default setting of a transaction annotation.
	 */
@Transactional(propagation= Propagation.REQUIRED)
           

1、表示支持当前的事务,如果没有就创建事务。

Spring boot 整合 jdbcTemplate &amp; 事务 三

我在都添加了方法。

在 logServiceImpl 中添加了

@Override
    @Transactional(propagation= Propagation.REQUIRED)
    public void info(String msg, Integer err) {
        String sql="INSERT INTO log (message,err) VALUES( ?, ?)";
        jdbcTemplate.update(sql,msg,err);
    }
           

在 userServiceImpl

@Override
    @Transactional(propagation= Propagation.REQUIRED)
    public void update(String name, Integer age) {
       String sql = "INSERT INTO user (name, age ) VALUES ( ? , ?)";
       jdbcTemplate.update(sql,name,age);
    }
           

在controller 中

@RequestMapping("/test")
    @Transactional(propagation = Propagation.REQUIRED)
    public String requiredTest(){
        userService.update("t1",12);
        int c =1 /0;
        logService.info("m1",0);
        return "success";
    }
           

代码意味着每个方法都有一个事务,controller 中 userService 服务是否能够执行成功?

Spring boot 整合 jdbcTemplate &amp; 事务 三

查看数据库:

Spring boot 整合 jdbcTemplate &amp; 事务 三

发现并没有执行成功。哪个语义的意思。如果当前的方法上被添加了事务,那么userService.update 的事务就不在创建了,支持当前的事务。

---

//Support a current transaction, execute non-transactionally if none exists.
@Transactional(propagation= Propagation.SUPPORTS)
           

支持当前的事务,如果没有就非事务性的。

//Support a current transaction, throw an exception if none exists.
@Transactional(propagation= Propagation.MANDATORY)
           

支持当前的事务,如果不存在事务,就抛出异常

//Create a new transaction, and suspend the current transaction if one exists.
@Transactional(propagation= Propagation.REQUIRES_NEW)
           

创建一个新的事务,挂起当前的事务,新事物执行完成后,在继续执行当前的事务。

把 userService logService 改为 Requires_new 事务类型。

@Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void info(String msg, Integer err) {
        String sql="INSERT INTO log (message,err) VALUES( ?, ?)";
        jdbcTemplate.update(sql,msg,err);
    }
           
@Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void update(String name, Integer age) {
       String sql = "INSERT INTO user (name, age ) VALUES ( ? , ?)";
       jdbcTemplate.update(sql,name,age);
    }
           
@RequestMapping("/test_new")
    @Transactional(propagation = Propagation.REQUIRED)
    public String newTranTest(){
        userService.update("t1",12);
        int c =1 /0;
        logService.info("m1",0);
        return "success";
    }
           

这种情况下,当前存在事务, userservice.update 是否可以执行成功呢?

Spring boot 整合 jdbcTemplate &amp; 事务 三
Spring boot 整合 jdbcTemplate &amp; 事务 三

userService 是更新成功的,也就是说这个两个独立的事务。如果userService 报错了,方法没有报错,被捕获。

PROPAGATION_NOT_SUPPORTED 、NEVER  很好理解,不支持事务。      

-- 事务嵌套。

NESTED 

Execute within a nested transaction if a current transaction exists,      

     他与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立,而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。而Nested事务的好处是他有一个savepoint。

继续阅读