天天看點

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。

繼續閱讀