事務首先是一系列操作組成的工作單元,該工作單元內的操作是不可分割的,即要麼所有操作都做,要麼所有操作都不做
ACID
1.原子性(Atomicity)
即事務是不可分割的最小工作單元,事務內的操作要麼全做,要麼全不做
2.一致性(Consistency)
在事務執行前數據庫的數據處於正確的狀態,而事務執行完成後數據庫的數據還是處於正確的狀態,即數據完整性約束沒有被破壞
如銀行轉帳,A轉帳給B,必須保證A的錢一定轉給B,一定不會出現A的錢轉了但B沒收到,否則數據庫的數據就處於不一致(不正確)的狀態
3.隔離性(Isolation)
併發事務執行之間無影響,在一個事務內部的操作對其他事務是不產生影響,這需要事務隔離級別來指定隔離性
4.持久性(Durability)
事務一旦執行成功,它對數據庫的數據的改變必須是永久的,不會因比如遇到系統故障或斷電造成數據不一致或丟失
常見問題
1.丟失更新
兩個事務同時更新一行數據,最後一個事務的更新會覆蓋掉第一個事務的更新,從而導致第一個事務更新的數據丟失,這是由於沒有加鎖造成的
2.髒讀
一個事務看到了另一個事務未提交的更新數據
3.不可重複讀
在同一事務中,多次讀取同一數據卻返回不同的結果;也就是有其他事務更改了這些數據
不可重複讀的重點是修改
4.幻讀
一個事務在執行過程中讀取到了另一個事務已提交的插入數據;即在第一個事務開始時讀取到一批數據,但此後另一個事務又插入了新數據並提交,此時第一個事務又讀取這批數據但發現多了一條,即好像發生幻覺一樣
幻讀的重點在於新增或者刪除
隔離級別
1.未提交讀(Read Uncommitted)
最低隔離級別,一個事務能讀取到別的事務未提交的更新數據,很不安全,可能出現丟失更新、髒讀、不可重複讀、幻讀
2.提交讀(Read Committed)
一個事務能讀取到別的事務提交的更新數據,不能看到未提交的更新數據,不可能可能出現丟失更新、髒讀,但可能出現不可重複讀、幻讀
3.可重複讀(Repeatable Read)
保證同一事務中先後執行的多次查詢將返回同一結果,不受其他事務影響,可能出現丟失更新、髒讀、不可重複讀,但可能出現幻讀
4.序列化(Serializable)
最高隔離級別,不允許事務併發執行,而必須串行化執行,最安全,不可能出現更新、髒讀、不可重複讀、幻讀
隔離級別越高,數據庫事務併發執行性能越差,能處理的操作越少。因此在實際項目開發中爲了考慮併發性能一般使用提交讀隔離級別,它能避免丟失更新和髒讀,儘管不可重複讀和幻讀不能避免,但可以在可能出現的場合使用悲觀鎖或樂觀鎖來解決這些問題
從數據庫系統的角度來看,鎖分爲以下三種類型
1.獨佔鎖(Exclusive Lock)
獨佔鎖鎖定的資源只允許進行鎖定操作的程序使用,其它任何對它的操作均不會被接受。執行數據更新命令,即INSERT、 UPDATE 或DELETE 命令時,SQL Server 會自動使用獨佔鎖。但當對象上有其它鎖存在時,無法對其加獨佔鎖。獨佔鎖一直到事務結束才能被釋放
2.共享鎖(Shared Lock)
共享鎖鎖定的資源可以被其它用戶讀取,但其它用戶不能修改它。在SELECT 命令執行時,SQL Server 通常會對對象進行共享鎖鎖定。通常加共享鎖的數據頁被讀取完畢後,共享鎖就會立即被釋放
3.更新鎖(Update Lock)
更新鎖是爲了防止死鎖而設立的。當SQL Server 準備更新數據時,它首先對數據對象作更新鎖鎖定,這樣數據將不能被修改,但可以讀取。等到SQL Server 確定要進行更新數據操作時,它會自動將更新鎖換爲獨佔鎖。但當對象上有其它鎖存在時,無法對其作更新鎖鎖定
從程序員的角度看,鎖分爲以下兩種類型
1.悲觀鎖(Pessimistic Lock)
悲觀鎖,正如其名,它指的是對數據被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此在整個數據處理過程中,將數據處於鎖定狀態。悲觀鎖的實現,往往依靠數據庫提供的鎖機制(也只有數據庫層提供的鎖機制才能真正保證數據訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改數據)
2.樂觀鎖(Optimistic Lock)
相對悲觀鎖而言,樂觀鎖機制採取了更加寬鬆的加鎖機制。悲觀鎖大多數情況下依靠數據庫的鎖機制實現,以保證操作最大程度的獨佔性。但隨之而來的就是數據庫性能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受
而樂觀鎖機制在一定程度上解決了這個問題。樂觀鎖,大多是基於數據版本( Version )記錄機制實現。何謂數據版本?即爲數據增加一個版本標識,在基於數據庫表的版本解決方案中,一般是通過爲數據庫表增加一個 “version” 字段來實現。讀取出數據時,將此版本號一同讀出,之後更新時,對此版本號加一。此時,將提交數據的版本數據與數據庫表對應記錄的當前版本信息進行比對,如 果提交的數據版本號大於數據庫表當前版本號,則予以更新,否則認爲是過期數據
數據庫事務類型
本地事務
就是普通事務,能保證單臺數據庫上的操作的ACID,被限定在一臺數據庫上
分佈式事務
涉及兩個或多個數據庫源的事務,即跨越多臺同類或異類數據庫的事務(由每臺數據庫的本地事務組成的),分佈式事務旨在保證這些本地事務的所有操作的ACID,使事務可以跨越多臺數據庫
Java事務類型
JDBC事務:就是數據庫事務類型中的本地事務,通過Connection對象的控制來管理事務
JTA事務:JTA指Java事務API(Java Transaction API),是Java EE數據庫事務規範, JTA只提供了事務管理接口,由應用程序服務器廠商(如WebSphere Application Server)提供實現,JTA事務比JDBC更強大,支持分佈式事務
Java EE事務類型
本地事務:使用JDBC編程實現事務
全局事務:由應用程序服務器提供,使用JTA事務
編程實現
聲明式事務: 通過註解或XML配置文件指定事務信息
編程式事務:通過編寫代碼實現事務
Spring事務使用
說明
結構
DataSource
JdbcDataSource
SessionFactory
EntityManager
TransactionManager
DataSourceTransactionManager
HibernateTransactionManager
JpaTransactionManager
代理機制
Bean和代理
每個Bean有一個代理
所有Bean共享一個代理基類
使用攔截器
使用TX標籤配置的攔截器
全註解配置
無論哪種配置方式,一般變化的只是代理機制這部分
5種實現方式
1.每個Bean都有一個代理
每個Bean用TransactionProxyFactoryBean代理
2.所有Bean共享一個代理基類
所有Bean都集成TransactionProxyFactoryBean
3.使用攔截器
攔截器:TransactionInterceptor
根據beanName匹配後進行自動代理: BeanNameAutoProxyCreator
4.使用tx標籤配置的攔截器
<tx:advice/>
<aop:config/>
5.全註解
Transactional
更多內容請關注微信公衆號:IT哈哈(it_haha)