一、事務
1、事務的四大特性
(1)原子性:事務開始后所有的操作要么一起成功,要么一起失敗,整個事務是一個不可分割的整體。
(2)一致性:是物開始前到結束后,數據庫的完整性約束沒有被破壞。
(3)隔離性:同一時間只允許一個事務請求同一事務,不同事務互不干擾。
(4)持久性:事務完成,事務對數據庫的所有更新將被保存到數據庫,不能回滾。
tps:數據庫的完整性約束-->數據完整性:存儲在數據庫中的所有數據值均正確的狀態。它是應防止數據庫中存在不符合語義規定的數據和防止因錯誤信息的輸入輸出造成無效操作或錯誤信息而提出的。數據完整性分為四類: 1. 實體完整性(實體完整性是對關系中的記錄唯一性,也就是主鍵的約束。准確地說,實體完整性是指關系中的主屬性值不能為Null且不能有相同值。定義表中的所有行能唯一的標識,一般用主鍵,唯一索引 unique關鍵字,及identity屬性比如說我們的身份證號碼,可以唯一標識一個人.。) 2. 域完整性(域完整性是對數據表中字段屬性的約束,通常指數據的有效性,它包括字段的值域、字段的類型及字段的有效規則等約束,它是由確定關系結構時所定義的字段的屬性決定的。限制數據類型,缺省值,規則,約束,是否可以為空,域完整性可以確保不會輸入無效的值.。) 3. 參照完整性(參照完整性是對關系數據庫中建立關聯關系的數據表間數據參照引用的約束,也就是對外鍵的約束。准確地說,參照完整性是指關系中的外鍵必須是另一個關系的主鍵有效值,或者是NULL。參考完整性維護表間數據的有效性,完整性,通常通過建立外部鍵聯系另一表的主鍵實現,還可以用觸發器來維護參考完整性) 4. 用戶定義的完整性。 約束是表級的強制規定,有以下五中:not null,unique,primary key,foreign key,check 。 |
2、事務的隔離級別
事務隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
讀未提交(read-uncommitted) | 是 | 是 | 是 |
不可重復讀(read-committed) | 否 | 是 | 是 |
可重復讀(repeatable-read) (mysql默認) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
(1)臟讀:事務A讀取到事務B未提交的數據(事務B回滾可怎么辦)。
(2)不可重復讀:事務A在同一事務中多次讀取同一數據,取到不同的值。(有其他事務在A事務期間更新了這一數據、或刪除,導致)
(3)幻讀:事務A兩次讀取數據,返回的數據條數不一致(發生增加)
二、行鎖
1、樂觀鎖
樂觀鎖並不是數據庫本身實現的,他需要我們自己去實現。
每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量,像數據庫提供的類似於write_condition機制,其實都是提供的樂觀鎖。在Java中java.util.concurrent.atomic包下面的原子變量類就是使用了樂觀鎖的一種實現方式CAS實現的。
2、悲觀鎖
總是假設最壞的情況,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖。傳統的關系型數據庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。再比如Java里面的同步原語synchronized關鍵字的實現也是悲觀鎖。
悲觀鎖涉及到另外兩個鎖概念,它們就是共享鎖與排它鎖。共享鎖和排它鎖是悲觀鎖的不同的實現,它倆都屬於悲觀鎖的范疇。
1)共享鎖:對於多個事務對同一資源共享一把鎖
在執行語句后面加上lock in share mode就代表對某些資源加上共享鎖了
2)排它鎖:對於多個事務對同一資源只能有一把鎖
在執行語句后面加上for update就代表對某些資源加上排它鎖了
3、悲觀鎖與掃描行:
對通過索引、主鍵查詢到的數據加鎖,會將這個索引所在的記錄加上鎖,如果通過條件查詢,會對多條記錄加上鎖。
如果不加索引,MySQL 會對掃描到的數據加鎖。(不確定)
SpringMVC @Transactional 注解
@Transactional 在方法頭上注解,該方法被其他方法內部調用,則不會生效。
另需要手動開啟事務用:
1 @Autowired 2 private PlatformTransactionManager transactionManager; 3 4 DefaultTransactionDefinition def=new DefaultTransactionDefinition(); 5 def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔離級別,開啟新事務,這樣會比較安全些。 6 TransactionStatus status = transactionManager.getTransaction(def); // 獲得事務狀態 7 transactionManager.commit(status);//提交 8 transactionManager.rollback(status);//回滾