您好,登錄后才能下訂單哦!
這篇文章主要介紹“SpringBoot事務管理實例分析”,在日常操作中,相信很多人在SpringBoot事務管理實例分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”SpringBoot事務管理實例分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
事務是由 N 步數據庫操作序列組成的邏輯執行單元,這系列操作要么全部執行,要么全部放棄執行。
事務的 ACID
特性:
原子性:事務是應用中不可分割的最小執行體
一致性:事務執行的結果必須使得數據從一個一致性狀態轉變為另一個一致性狀態
隔離性:各個事務的執行互不干擾,任何事務的內部操作對其他事務都是隔離的
持久性:事務一旦提交,對數據所做的任何修改都要記錄到永久存儲器中
常見的并發異常
第一類丟失更新、第二類丟失更新
臟讀、不可重復讀、幻讀
常見的隔離級別
Read Uncommitted:讀取未提交的數據
Read Commited:讀取已提交的數據
Repeatable Read:可重復讀
Serializable:串行化
第一類更新丟失:某一個事務的回滾,導致另一個事務已更新的數據丟失了。
第二類更新丟失:某一個事務的提交,導致另一個事務已更新的數據丟失了。
臟讀:某一個事務,讀取了另一個事務未提交的數據。
不可重復讀:某一個事務,對同一個數據前后讀取的結果不一致。
幻讀:某一個事務,對同一個表前后查詢到的行數不一致。
隔離級別 | 第一類丟失更新 | 臟讀 | 第二類丟失更新 | 不可重復讀 | 幻讀 |
---|---|---|---|---|---|
Read Uncommitted | 是 | 是 | 是 | 是 | 是 |
Read Commited | 否 | 否 | 是 | 是 | 是 |
Repeatable Read | 否 | 否 | 否 | 否 | 是 |
Repeatable Read | 否 | 否 | 否 | 否 | 否 |
實現機制
悲觀鎖(數據庫)
共享鎖(S鎖):事務A對某數據加了共享鎖以后,其他事務只能對該數據加共享鎖,但不能加排他鎖
排他鎖(X鎖):事務A對某數據加了排他鎖以后,其他事務對該數據既不能加共享鎖,也不能加排他鎖。
樂觀鎖(自定義)
版本號、時間戳等
在更新數據前,檢查版本號是否發生變化。若發生變化則取消本次更新,否則就更新數據(版本號+1)
Spring 事務管理
聲明式事務
通過 XML 配置,聲明某方法的事務特征。
通過注解,聲明某方法的事務特征。
編程式事務
通過 TransactionTemplate管理事務,并通過它執行數據庫的操作。
package com.nowcoder.community.service; import com.nowcoder.community.dao.AlphaDao; import com.nowcoder.community.dao.DiscussPostMapper; import com.nowcoder.community.dao.UserMapper; import com.nowcoder.community.entity.DiscussPost; import com.nowcoder.community.entity.User; import com.nowcoder.community.util.CommunityUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.Date; @Service //@Scope("prototype") public class AlphaService { @Autowired private AlphaDao alphaDao; @Autowired private UserMapper userMapper; @Autowired private DiscussPostMapper discussPostMapper; @Autowired private TransactionTemplate transactionTemplate; public AlphaService() { // System.out.println("實例化AlphaService"); } @PostConstruct public void init() { // System.out.println("初始化AlphaService"); } @PreDestroy public void destroy() { // System.out.println("銷毀AlphaService"); } public String find() { return alphaDao.select(); } // REQUIRED: 支持當前事務(外部事務),如果不存在則創建新事務. // REQUIRES_NEW: 創建一個新事務,并且暫停當前事務(外部事務). // NESTED: 如果當前存在事務(外部事務),則嵌套在該事務中執行(獨立的提交和回滾),否則就會REQUIRED一樣. @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED) public Object save1() { // 新增用戶 User user = new User(); user.setUsername("alpha"); user.setSalt(CommunityUtil.generateUUID().substring(0, 5)); user.setPassword(CommunityUtil.md5("123" + user.getSalt())); user.setEmail("alpha@qq.com"); user.setHeaderUrl("https://cache.yisu.com/upload/information/20220823/112/6198.png"); user.setCreateTime(new Date()); userMapper.insertUser(user); // 新增帖子 DiscussPost post = new DiscussPost(); post.setUserId(user.getId()); post.setTitle("Hello"); post.setContent("新人報道!"); post.setCreateTime(new Date()); discussPostMapper.insertDiscussPost(post); Integer.valueOf("abc"); return "ok"; } public Object save2() { transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); return transactionTemplate.execute(new TransactionCallback<Object>() { @Override public Object doInTransaction(TransactionStatus status) { // 新增用戶 User user = new User(); user.setUsername("beta"); user.setSalt(CommunityUtil.generateUUID().substring(0, 5)); user.setPassword(CommunityUtil.md5("123" + user.getSalt())); user.setEmail("beta@qq.com"); user.setHeaderUrl("https://cache.yisu.com/upload/information/20220823/112/6199.png"); user.setCreateTime(new Date()); userMapper.insertUser(user); // 新增帖子 DiscussPost post = new DiscussPost(); post.setUserId(user.getId()); post.setTitle("你好"); post.setContent("我是新人!"); post.setCreateTime(new Date()); discussPostMapper.insertDiscussPost(post); Integer.valueOf("abc"); return "ok"; } }); } }
到此,關于“SpringBoot事務管理實例分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。