咱們在開發時,會對數據進行持久化操做,如存入數據庫中。當咱們操做數據庫中的數據,後續可能會發生錯誤,拋出異常,前面對數據庫的操做就會不可靠,在這種狀況下須要回滾。spring
事務的做用就是保證在事務中每一步操做都是可靠的,每一步操做均可以成功執行,中途出現錯誤或異常都要還原到事務開始前的狀態。數據庫
數據庫事務的隔離級別有4個,由低到高依次爲Read uncommitted、Read committed、Repeatable read、Serializable,這四個級別能夠逐個解決髒讀、不可重複讀、幻讀這幾類問題。數組
名詞解釋:併發
髒讀(Drity Read):某個事務已更新一份數據,另外一個事務在此時讀取了同一份數據,因爲某些緣由,前一個RollBack了操做,則後一個事務所讀取的數據就會是不正確的。性能
不可重複讀(Non-repeatable read):在一個事務的兩次查詢之中數據不一致,這多是兩次查詢過程當中間插入了一個事務更新的原有的數據。this
spring 中的實現:spa
public enum Isolation { // 底層數據庫默認的隔離等級 DEFAULT(-1), // 一個事務能夠讀取另外一個事務修改但尚未提交的數據。 READ_UNCOMMITTED(1), // 該隔離級別表示一個事務只能讀取另外一個事務已經提交的數據。 READ_COMMITTED(2), // 該隔離級別表示一個事務在整個過程當中能夠屢次重複執行某個查詢,而且每次返回的記錄都相同。即便在屢次查詢之間有新增的數據知足該查詢,這些新增的記錄也會被忽略。 REPEATABLE_READ(4), // 全部的事務依次逐個執行,這樣事務之間就徹底不可能產生干擾,也就是說,該級別能夠防止髒讀、不可重複讀以及幻讀。 SERIALIZABLE(8); private final int value; private Isolation(int value) { this.value = value; } public int value() { return this.value; } }
2.2.1 PROPAGATION_REQUIRED:若是當前沒有事務,就建立一個新事務,若是當前存在事務,就加入該事務,該設置是最經常使用的設置。代理
2.2.2 PROPAGATION_SUPPORTS:支持當前事務,若是當前存在事務,就加入該事務,若是當前不存在事務,就以非事務執行。code
2.2.3 PROPAGATION_MANDATORY:支持當前事務,若是當前存在事務,就加入該事務,若是當前不存在事務,就拋出異常。對象
2.2.4 PROPAGATION_REQUIRES_NEW:建立新事務,不管當前存不存在事務,都建立新事務。
2.2.5 PROPAGATION_NOT_SUPPORTED:以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
2.2.6 PROPAGATION_NEVER:以非事務方式執行,若是當前存在事務,則拋出異常。
2.2.7 PROPAGATION_NESTED:若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則執行與PROPAGATION_REQUIRED相似的操做。
spring的實現:
public enum Propagation { // 若是當前存在事務,則加入該事務;若是當前沒有事務,則建立一個新的事務。 // @Transactional 註解默認採用這個方案 REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED), // 若是當前存在事務,則加入該事務;若是當前沒有事務,則以非事務的方式繼續運行。 SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS), // 若是當前存在事務,則加入該事務;若是當前沒有事務,則拋出異常。 MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY), // 建立一個新的事務,若是當前存在事務,則把當前事務掛起。 REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW), // 以非事務方式運行,若是當前存在事務,則把當前事務掛起。 NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED), // 以非事務方式運行,若是當前存在事務,則拋出異常。 NEVER(TransactionDefinition.PROPAGATION_NEVER), // 若是當前存在事務,則建立一個事務做爲當前事務的嵌套事務來運行;若是當前沒有事務,則該取值等價於REQUIRED // 並不是全部的TransactionManager都能支持這個傳播級別 NESTED(TransactionDefinition.PROPAGATION_NESTED); private final int value; Propagation(int value) { this.value = value; } public int value() { return this.value; } }
@Transactional註解中經常使用參數說明
參數名稱 |
功能描述 |
readOnly |
該屬性用於設置當前事務是否爲只讀事務,設置爲true表示只讀,false則表示可讀寫,默認值爲false。例如:@Transactional(readOnly=true) |
rollbackFor |
該屬性用於設置須要進行回滾的異常類數組,當方法中拋出指定異常數組中的異常時,則進行事務回滾。例如: 指定單一異常類:@Transactional(rollbackFor=RuntimeException.class) 指定多個異常類:@Transactional(rollbackFor={RuntimeException.class, Exception.class}) |
rollbackForClassName |
該屬性用於設置須要進行回滾的異常類名稱數組,當方法中拋出指定異常名稱數組中的異常時,則進行事務回滾。例如: 指定單一異常類名稱:@Transactional(rollbackForClassName="RuntimeException") 指定多個異常類名稱:@Transactional(rollbackForClassName={"RuntimeException","Exception"}) |
noRollbackFor |
該屬性用於設置不須要進行回滾的異常類數組,當方法中拋出指定異常數組中的異常時,不進行事務回滾。例如: 指定單一異常類:@Transactional(noRollbackFor=RuntimeException.class) 指定多個異常類:@Transactional(noRollbackFor={RuntimeException.class, Exception.class}) |
noRollbackForClassName |
該屬性用於設置不須要進行回滾的異常類名稱數組,當方法中拋出指定異常名稱數組中的異常時,不進行事務回滾。例如: 指定單一異常類名稱:@Transactional(noRollbackForClassName="RuntimeException") 指定多個異常類名稱: @Transactional(noRollbackForClassName={"RuntimeException","Exception"}) |
propagation |
該屬性用於設置事務的傳播行爲,具體取值可參考表6-7。 例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true) |
isolation |
該屬性用於設置底層數據庫的事務隔離級別,事務隔離級別用於處理多事務併發的狀況,一般使用數據庫的默認隔離級別便可,基本不須要進行設置 |
timeout |
該屬性用於設置事務的超時秒數,默認值爲-1表示永不超時 |
@Transactional(rollbackFor=Exception.class) //指定回滾,遇到異常Exception時回滾 public void methodName() { throw new Exception("註釋"); } @Transactional(noRollbackFor=Exception.class)//指定不回滾,遇到運行期例外(throw new RuntimeException("註釋");)會回滾 public ItimDaoImpl getItemDaoImpl() { throw new RuntimeException("註釋"); }