標籤:select on() exce 持久 準備 取資料 ons 不一致 als
(一)什麼是事務
事務:是資料庫的概念,邏輯上的一組操作,組成這級操作的各個單元,要麼全部成功,要麼全部失敗。
主要是針對批量的insert、update、delete語句
(二)事務的作用
保證多條SQL的資料變更,要麼全部成功,要麼全部失敗。
在實際業務情境裡,通常會遇到一些特殊的業務:這些業務需要由多條SQL操作來一起完成。如果沒有事務,那麼每執行一條SQL,資料變更會立即生效;但是如果在執行過程中,某一條SQL執行失敗或者出現了異常,前邊的SQL變更已經生效,但是後邊的SQL就不執行了,造成的後果就是:業務完成了一半,一半成功,一半失敗。
就可以使用事務來保證業務裡的多條SQL,要麼一起成功,要麼一起失敗。
開啟事務:
執行多條SQL語句 ----開啟事務之後,執行的SQL不會立即生效,而是被資料庫暫時儲存起來
關閉事務
提交事務:剛剛執行的所有SQL的變更,會立即全部生效,持久化儲存到資料庫裡
復原事務:剛剛執行的所有sqlr變更,會全部撤消,資料復原到執行之前的狀態
(三)MySql的交易管理(瞭解)
MySql的交易管理,預設是自動認可的。
MySql提供了兩種交易管理的方式:
自動管理:
關閉自動認可:set autocommit=0;
執行n條SQL語句
提交事務/復原事務: commit/rollback
手動管理:
手動開啟事務: start transaction;
執行n條SQL語句
手動提交事務/復原事務: commit/rollback;
一、JDBC的交易管理(一)JDBC交易管理簡介
操作資料庫一般是由Java程式來操作,那麼交易管理也需要由Java程式來進行管理。就需要使用JDBC來管理事務。
(二)JDBC事務相關的API
JDBC裡交易管理是基於Connection對象的。
開啟事務:conn.setAutoCommit(false);
提交事務:conn.commit();
復原事務:conn.rollback();
使用JDBC管理事務的步驟:
註冊驅動
擷取串連
開啟事務
建立SQL執行平台
執行SQL語句
關閉事務:提交事務/復原事務
釋放資源
二、DBUtils的交易管理(重點)
DBUtils的本質仍然是JDBC,所以DBUtils的交易管理,也是基於Connection對象的。
無事務的DBUtils操作
建立QueryRunner對象:有參構造方法,把串連池對象傳遞進去
QueryRunner runner = new QueryRunner(串連池對象);/執行SQL語句
runner.update(sql, Object… params);
交易管理相關的DBUtils操作
建立QueryRunner對象:使用無參構造
QueryRunner runner = new QueryRunner();
執行SQL時,需要傳遞一個開啟了事務的Connection對象給runner來執行SQL
runner.update(conn, sql, params);
三、ThreadLocal(應用)
什麼是ThreadLocal
是JDK提供的一個類,java.lang.ThreadLocal。 線程局部變數。可以實現線上程的進行變數的共用
ThreadLocal有什麼用
在某一個代碼裡,使用ThreadLocal向當前線程中綁定一個資料,當線程執行到後邊其它代碼的時候,就可以從當前線程擷取到綁定的變數的值。
可以理解為:實現隱式傳參的
比如:
顯式傳參:service傳參conn給dao
dao.outMoney(conn);
隱式傳參:service傳參conn給dao
在service裡,把conn綁定到當前線程上
線程會調用dao的代碼:dao.outMoney()
在dao裡,從當前線程上擷取到綁定的conn對象
ThreadLocal相關的API
構造方法:ThreadLocal<T>();
向當前線程上綁定資料:tl.set(value);
從當前線程上取資料:tl.get();
從當前線程上刪除資料:tl.remove();
使用ThreadLocal最佳化工具類,進行交易管理
Service代碼:
try{
JdbcUtils.startTransaction();
調用dao的方法,不需要傳參Connection對象。可以調用多個dao的方法,屬於同一個事務
JdbcUtils.commitAndClose();
}catch(Exception e){
JdbcUtils.rollbackAndClose();
}
Dao的代碼:
使用無參構造建立一個QueryRunner對象:runner
runner.update(JdbcUtils.getConnection(), sql, params);
四、事務的特性(一)事務的特性ACID
A :Atomicity 原子性,表示一個事務裡的多個操作是不可分割的,一個事務的所有操作,要麼全部成功,要麼全部失敗。
C :Consistency 一致性,表示事務提交前後,資料是一致的。
I :Isolation 隔離性,表示多個事務之間,應該是相互獨立,互不干擾的。
D :Durability 持久性,表示事務提交之後,資料就持久化儲存到了資料庫裡。
(二)事務並發存在的問題
是在不考慮事務的隔離性,或者隔離性比較弱的情況下,存在的事務並發問題。
髒讀:一個事務讀取到了另外一個事務未提交的資料。(最嚴重的問題,必須要避免的問題)
不可重複讀取:一個事務讀取到另外一個事務裡的update的變更。
虛讀/幻讀:一個事務讀取到另外一個事務裡的insert、delete的變更。
(三)事務的隔離等級
read uncommitted:未提交讀,存在髒讀、不可重複讀取、虛讀
read committed:已提交讀,不存在髒讀,存在不可重複讀取、虛讀
repeatable read:可重複讀,不存在髒讀、不可重複讀取,存在虛讀
serializable:序列化,同一時間只有一個事務在執行,其它事務排隊等候,所有問題都不存在
安全性比較:serializable > repeatable read > read committed > read uncommitted
效能比較:serializable < repeatable read < read committed < read uncommitted
MySql的預設隔離等級是:repeatable read
Oracle的預設隔離等級是:read committed
MySql:
查看事務的隔離等級:select @@tx_isolatioin
設定事務的隔離等級:set session transaction isolation level 隔離等級
(四)不同交易隔離等級的示範
準備:
開啟A和B兩個用戶端,都串連上MySql。把A作為示範會話,把B作為幹擾會話。
l read uncommited
設定A的隔離等級為read uncommitted
A和B都開啟事務
A查詢一下資料----看一下表的未經處理資料是什麼樣的
B執行update,但不提交事務
A重新查詢資料----看資料有沒有變更,如果有變數,就說明讀到了B未提交的資料----存在髒讀
read commited
設定A的隔離等級為read commited
A和B都開啟事務
A查詢資料---看未經處理資料
B執行update但不提交
A重新查詢----確認髒讀問題是否解決:已經解決
B提交事務
A重新查詢----看資料和剛剛查詢是否一致:資料不一致,存在不可重複讀取問題
repeatable read
設定A的隔離等級為repeatable read
A和B同時開啟事務
A查詢資料—查看未經處理資料
B執行update但不提交
A重新查詢----確認髒讀是否解決:已經解決
B提交事務
A重新查詢----確認不可重複讀取是否解決:已經解決
A關閉事務
A查詢資料----確認資料是否已經真實變更到資料庫
serializable
設定A的隔離等級為serializable
A和B同時開啟事務
A查詢資料
B執行update操作---會處於等待狀態,等A事務結束
有兩種結果:
等待逾時
A事務結束了,B事務會立即執行
JDBC進階-事務