1. 程式人生 > 其它 >springboot mybatis 事務管理

springboot mybatis 事務管理

本文主要講述springboot提供的宣告式的事務管理機制。

一、一些概念

宣告式的事務管理是基於AOP的,在springboot中可以通過@Transactional註解的方式獲得支援,這種方式的優點是:

1)非侵入式,業務邏輯不受事務管理程式碼的汙染。

2)方法級別的事務回滾,合理劃分方法的粒度可以做到符合各種業務場景的事務管理。

本文使用目前最常用的mybatis框架來配置springboot的事務管理機制。下面進入配置方法介紹。

二、springboot mybatis事務配置

1、看一下pom依賴

其中:

1)<parent></parent>標籤引入springboot父依賴

2)使用了spring和mybatis整合包,整合spring和mybatis

3)mysql資料庫驅動包

4)序列化支援fastjson

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.19</version>
        </dependency>
    </dependencies>

2、application.properties

這個配置主要是實現配置mybatis資料來源,這超出了本文的敘述範圍,大家可以參照這篇部落格。http://www.cnblogs.com/kangoroo/p/7133543.html

# 主資料來源 moonlight
spring.datasource.moonlight.driverClassName = com.mysql.jdbc.Driver
spring.datasource.moonlight.url=jdbc:mysql://10.93.84.53:3306/moonlight?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&autoReconnect=true&failOverReadOnly=false
spring.datasource.moonlight.username = root
spring.datasource.moonlight.password = 1234
spring.datasource.moonlight.poolMaximumActiveConnections=400
spring.datasource.moonlight.poolMaximumIdleConnections=200
spring.datasource.moonlight.poolMaximumCheckoutTime=20000

之後你可以根據新增的資料來源,寫好mapper也就是dao層程式碼。

DAO層程式碼是使用XML配置方式,還是使用註解實現方式,對事務管理都是沒有影響的。

3、Service層

在設計service層的時候,應該合理的抽象出方法包含的內容。

然後將方法用@Trasactional註解註釋,預設的話在丟擲Exception.class異常的時候,就會觸發方法中所有資料庫操作回滾,當然這指的是增、刪、改。

當然,@Transational方法是可以帶引數的,具體的引數解釋如下:

屬性

型別

描述

value

String

可選的限定描述符,指定使用的事務管理器

propagation

enum: Propagation

可選的事務傳播行為設定

isolation

enum: Isolation

可選的事務隔離級別設定

readOnly

boolean

讀寫或只讀事務,預設讀寫

timeout

int (in seconds granularity)

事務超時時間設定

rollbackFor

Class物件陣列,必須繼承自Throwable

導致事務回滾的異常類陣列

rollbackForClassName

類名陣列,必須繼承自Throwable

導致事務回滾的異常類名字陣列

noRollbackFor

Class物件陣列,必須繼承自Throwable

不會導致事務回滾的異常類陣列

noRollbackForClassName

類名陣列,必須繼承自Throwable

不會導致事務回滾的異常類名字陣列

給出一些示例程式碼

@Service
public class GeoFenceService {

    @Autowired
    private MoonlightMapper moonlightMapper;

    @Transactional
    public int addGeoFence(GeoFence geoFence) {
        String formatTime = TimeFunction.transTimeToFormatPerfect(System.currentTimeMillis());
        geoFence.setCreateTime(formatTime);
        geoFence.setUpdateTime(formatTime);
        return moonlightMapper.insertOne(geoFence);
    }

    @Transactional
    public int batchGeoFence(List<GeoFence> geoFenceList) {
        String formatTime = TimeFunction.transTimeToFormatPerfect(System.currentTimeMillis());
        for (GeoFence geoFence : geoFenceList) {
            geoFence.setCreateTime(formatTime);
            geoFence.setUpdateTime(formatTime);
        }
        return moonlightMapper.insertBatch(geoFenceList);
    }
}

4、開啟事務

最後你要在Application類中開啟事務管理,開啟事務管理很簡單,只需要@EnableTransactionManagement註解就行

@EnableTransactionManagement
@SpringBootApplication
public class WebApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
}

三、測試一下

可以做一個簡單的測試,主動丟擲異常,測試一下是否真的能保證事務性。

在執行完插入之後,手動丟擲一個空指標異常,可以發現數據真的回滾了。

@Service
public class GeoFenceService {

    @Autowired
    private MoonlightMapper moonlightMapper;

    @Transactional
    public int addGeoFence(GeoFence geoFence) {
        String formatTime = TimeFunction.transTimeToFormatPerfect(System.currentTimeMillis());
        geoFence.setCreateTime(formatTime);
        geoFence.setUpdateTime(formatTime);
        int count = moonlightMapper.insertOne(geoFence);
        String a = null;
        a.indexOf('c');
        return count;
    }
}