springBoot(14):使用SQL關(guān)系型數(shù)據(jù)庫-事務(wù)處理

一、事務(wù)的四個特性(ACID)

成都創(chuàng)新互聯(lián)公司公司2013年成立,先為昌平等服務(wù)建站,昌平等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為昌平企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

原子性(Atomicity):

 事務(wù)是一個原子操作,由一系列動作組成。事務(wù)的原子性確保動作要么全部完成,要么完全不起作用。

一致性(Consistency):

 一旦事務(wù)完成(不管成功還是失敗),系統(tǒng)必須確保它所建模的業(yè)務(wù)處于一致的狀態(tài),而不會是部分完成部分失敗。在現(xiàn)實中的數(shù)據(jù)不應(yīng)該被破壞。

隔離性(Isolation):

 可能有許多事務(wù)會同時處理相同的數(shù)據(jù),因此每個事務(wù)都應(yīng)該與其他事務(wù)隔離開來,防止數(shù)據(jù)損壞。

持久性(Durability):

 一旦事務(wù)完成,無論發(fā)生什么系統(tǒng)錯誤,它的結(jié)果都不應(yīng)該受到影響,這樣就能從任何系統(tǒng)崩潰中恢復(fù)過來。通常情況下,事務(wù)的結(jié)果被寫到持久化存儲器中。

二、傳播行為

當(dāng)事務(wù)方法被另一個事務(wù)方法調(diào)用時,必須指定事務(wù)應(yīng)該如何傳播。

例如:方法可能繼續(xù)在現(xiàn)有事務(wù)中運行,也可能開啟一個新事務(wù),并在自己的事務(wù)中運行。

Spring 定義了七種傳播行為。

2.1、PROPAGATION_REQUIRED

表示當(dāng)前方法必須運行在事務(wù)中。如果當(dāng)前事務(wù)存在,方法將會在該事務(wù)中運行。否則,會啟動一個新的事務(wù), Spring 默認(rèn)使用

2.2、PROPAGATION_SUPPORTS

表示當(dāng)前方法不需要事務(wù)上下文,但是如果存在當(dāng)前事務(wù)的話,那么該方法會在這個事務(wù)中運行

2.3、PROPAGATION_MANDATORY

表示該方法必須在事務(wù)中運行,如果當(dāng)前事務(wù)不存在,則會拋出一個異常

2.4、PROPAGATION_REQUIRED_NEW

表示當(dāng)前方法必須運行在它自己的事務(wù)中。一個新的事務(wù)將被啟動。如果存在當(dāng)前事務(wù),在該方法執(zhí)行期間,當(dāng)前事務(wù)會被掛起。如果使用 JTATransactionManager 的話,則需要訪問TransactionManager

2.5、PROPAGATION_NOT_SUPPORTED

表示該方法不應(yīng)該運行在事務(wù)中。如果存在當(dāng)前事務(wù),在該方法運行期間,當(dāng)前事務(wù)將被掛起。如果使用 JTATransactionManager 的話,則需要訪問 TransactionManager

2.6、PROPAGATION_NEVER

表示當(dāng)前方法不應(yīng)該運行在事務(wù)上下文中。如果當(dāng)前正有一個事務(wù)在運行,則會拋出異常

2.7、PROPAGATION_NESTED

表示如果當(dāng)前已經(jīng)存在一個事務(wù),那么該方法將會在嵌套事務(wù)中運行。嵌套的事務(wù)可以獨立于當(dāng)前事務(wù)進行單獨地提交或回滾。如果當(dāng)前事務(wù)不存在,那么其行為與PROPAGATION_REQUIRED 一樣。注意各廠商對這種傳播行為的支持是有所差異的??梢詤⒖假Y源管理器的文檔來確認(rèn)它們是否支持嵌套事務(wù)

三、隔離級別

隔離級別定義了一個事務(wù)可能受其他并發(fā)事務(wù)影響的程度。

3.1、ISOLATION_DEFAULT

使用后端數(shù)據(jù)庫默認(rèn)的隔離級別,Spring默認(rèn)使用,MySQL默認(rèn)的隔離級別為:Repeatable Read( ( 可重復(fù)讀) )

3.2、ISOLATION_READ_UNCOMMITTED

讀未提交,最低的隔離級別,允許讀取尚未提交的數(shù)據(jù)變更,可能會導(dǎo)致臟讀、幻讀或不可重復(fù)讀

3.3、ISOLATION_READ_COMMITTED 

讀已提交,允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù),可以阻止臟讀,但是幻讀或不可重復(fù)讀仍有可能發(fā)生

3.4、ISOLATION_REPEATABLE_READ 

可重復(fù)讀,對同一字段的多次讀取結(jié)果都是一致的,除非數(shù)據(jù)是被本身事務(wù)自己所修改,可以阻止臟讀和不可重復(fù)讀,但幻讀仍有可能發(fā)生

3.5、ISOLATION_SERIALIZABLE 

可串行化,最高的隔離級別,完全服從 ACID 的隔離級別,確保阻止臟讀、不可重復(fù)讀以及幻讀,也是最慢的事務(wù)隔離級別,因為它通常是通過完全鎖定事務(wù)相關(guān)的數(shù)據(jù)庫表來實現(xiàn)的

臟讀(Dirty reads):

 臟讀發(fā)生在一個事務(wù)讀取了另一個事務(wù)改寫但尚未提交的數(shù)據(jù)時。如果改寫再稍后被回滾了,那么第一個事務(wù)獲取的數(shù)據(jù)就是無效的。

不可重復(fù)讀(Nonrepeatable read):

 不可重復(fù)讀發(fā)生在一個事務(wù)執(zhí)行相同的查詢兩次或兩次以上,但是每次都得到不同的數(shù)據(jù)時。這通常是因為另一個并發(fā)事務(wù)在兩次查詢期間進行了更新。

幻讀(Phantom read):

 幻讀與不可重復(fù)讀類似。它發(fā)生在一個事務(wù)(T1)讀取了幾行數(shù)據(jù),接著另一個并發(fā)事務(wù)(T2)插入了一些數(shù)據(jù)時。在隨后的查詢中,第一個事務(wù)(T1)就會發(fā)現(xiàn)多了一些原本不存在的記錄。

四、操作

屬性說明 @Transactional

 a、isolation:用于指定事務(wù)的隔離級別。默認(rèn)為底層事務(wù)的隔離級別。

 b、noRollbackFor:指定遇到指定異常時強制不回滾事務(wù)。

 c、noRollbackForClassName:指定遇到指定多個異常時強制不回滾事務(wù)。該屬性可以指定多個異常類名。

 d、propagation:指定事務(wù)的傳播屬性。

 e、readOnly:指定事務(wù)是否只讀。表示這個事務(wù)只讀取數(shù)據(jù)但不更新數(shù)據(jù),這樣可以幫助數(shù)據(jù)庫引擎優(yōu)化事務(wù)。若真的是一個只讀取的數(shù)據(jù)庫應(yīng)設(shè)置 readOnly=true

 f、rollbackFor:指定遇到指定異常時強制回滾事務(wù)。

 g、rollbackForClassName:指定遇到指定多個異常時強制回滾事務(wù)。該屬性可以指定多個異常類名。

 h、timeout:指定事務(wù)的超時時長。

注 意:

 mysql為例,存儲引擎不能使用MyISAM,應(yīng)該使用InnoDB

package com.example.demo.service;

import com.example.demo.mapper.UserLogMapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.pojo.User;
import com.example.demo.pojo.UserLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * 描述
 *
 * @Author: 我愛大金子
 * @Description: 描述
 * @Date: Create in 10:18 2017/6/22
 */
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserLogMapper userLogMapper;
    /**
     * 用戶注冊
     *
     * @return
     */
    @Transactional
    public String register(String name, String ip) {
        // 1.添加用戶
        User user = new User();
        user.setName(name);
        user.setCreateTime(new Date());
        userMapper.insert(user);
        // 測試使用
        boolean flag = true;
        if (flag) {
            throw new RuntimeException();
        }
        // 2.添加注冊日志
        UserLog userLog = new UserLog();
        userLog.setUserName(name);
        userLog.setUserIp(ip);
        userLog.setCreateTime(new Date());
        userLogMapper.insert(userLog);
        return "success";
    }
}

測試:

package com.example.demo;

import com.example.demo.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Date;

@RunWith(SpringRunner.class)
@SpringBootTest
public class Springboot3ApplicationTests {

   @Autowired
   private UserService userService;

   @Test
   public void register() {
      String result = userService.register("張三", "192.168.1.1");
      System.out.println(result);
   }

}

效果:

springBoot(14):使用SQL關(guān)系型數(shù)據(jù)庫-事務(wù)處理

springBoot(14):使用SQL關(guān)系型數(shù)據(jù)庫-事務(wù)處理   springBoot(14):使用SQL關(guān)系型數(shù)據(jù)庫-事務(wù)處理

文章標(biāo)題:springBoot(14):使用SQL關(guān)系型數(shù)據(jù)庫-事務(wù)處理
網(wǎng)頁鏈接:http://muchs.cn/article18/ghijdp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗、網(wǎng)站改版、搜索引擎優(yōu)化品牌網(wǎng)站制作、品牌網(wǎng)站建設(shè)、網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)