1. 程式人生 > >輕鬆理解-中高階java開發必知必會之 事務@Transactional

輕鬆理解-中高階java開發必知必會之 事務@Transactional

事務,專案的重要部分,不可或缺。解決事務問題至關重要,即使出現異常情況,它也可以保證資料的一致性。。

在spring中對事務的操作有@Transactional註解去實現或者寫配置xml去實現,因為目前本人全面擁抱springboot框架,所以偏向於與註解的方式去實現;

一般我們會在server的實現類的頭上加註@Transactional,將兩個a,b連續操作的方法放入一個server方法中避免出現事務問題,如:

    @Transactional
    public class TestServiceBean implements TestService {
        private inertAB(XXX xx){
            insetA(xx);
            inserB(xx)
        }

那麼當一個inset方法出現問題後並回退後並不會執行第二個方法,及時是server方法中只有一個操作出現問題後,如資料庫連線中斷等也會回退

當我們在類頭上加了以後,我一個方法我不要加入事務的管理怎麼辦,添加註解:

@Transactional(propagation =Propagation.NOT_SUPPORTED)

下面還有詳細的一系列的引數和相關用途:

@Transactional(propagation=Propagation.REQUIRED) :如果有事務, 那麼加入事務, 沒有的話新建一個(預設情況下)
@Transactional(propagation=Propagation.NOT_SUPPORTED) :容器不為這個方法開啟事務
@Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事務,都建立一個新的事務,原來的掛起,新的執行完畢,繼續執行老的事務
@Transactional(propagation=Propagation.MANDATORY) :必須在一個已有的事務中執行,否則丟擲異常
@Transactional(propagation=Propagation.NEVER) :必須在一個沒有的事務中執行,否則丟擲異常(與Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.SUPPORTS) :如果其他bean呼叫這個方法,在其他bean中宣告事務,那就用事務.如果其他bean沒有宣告事務,那就不用事務.

事物超時設定:

  @Transactional(timeout=30) //預設是30秒

 

事務隔離級別:

  @Transactional(isolation = Isolation.READ_UNCOMMITTED):讀取未提交資料(會出現髒讀, 不可重複讀) 基本不使用
  @Transactional(isolation = Isolation.READ_COMMITTED):讀取已提交資料(會出現不可重複讀和幻讀)
  @Transactional(isolation = Isolation.REPEATABLE_READ):可重複讀(會出現幻讀)
  @Transactional(isolation = Isolation.SERIALIZABLE):序列化

  MYSQL: 預設為REPEATABLE_READ級別
  SQLSERVER: 預設為READ_COMMITTED

名詞解釋:

髒讀 : 一個事務讀取到另一事務未提交的更新資料
不可重複讀 : 在同一事務中, 多次讀取同一資料返回的結果有所不同, 換句話說, 後續讀取可以讀到另一事務已提交的更新資料. 相反, "可重複讀"在同一事務中多次
讀取資料時, 能夠保證所讀資料一樣, 也就是後續讀取不能讀到另一事務已提交的更新資料
幻讀 : 一個事務讀到另一個事務已提交的insert資料

注意的幾點:


  1、@Transactional 只能被應用到public方法上, 對於其它非public的方法,如果標記了@Transactional也不會報錯,但方法沒有事務功能.

  2、用 spring 事務管理器,由spring來負責資料庫的開啟,提交,回滾.預設遇到執行期例外(throw new RuntimeException("註釋");)會回滾,即遇到不受檢查(unchecked)的例外時回滾;而遇到需要捕獲的例外(throw new Exception("註釋");)不會回滾,即遇到受檢查的例外(就是非執行時丟擲的異常,編譯器會檢查到的異常叫受檢查例外或說受檢查異常)時,需我們指定方式來讓事務回滾要想所有異常都回滾,要加上 @Transactional( rollbackFor={Exception.class,其它異常}) .如果讓unchecked例外不回滾: @Transactional(notRollbackFor=RunTimeException.class)
如下:

@Transactional(rollbackFor=Exception.class) //指定回滾,遇到異常Exception時回滾
public void methodName() {
   throw new Exception("註釋");
}
@Transactional(noRollbackFor=Exception.class)//指定不回滾,遇到執行期例外(throw new RuntimeException("註釋");)會回滾
public ItimDaoImpl getItemDaoImpl() {
   throw new RuntimeException("註釋");
}

當然你你方法要是public的方法,不然即使不報錯也不會產生效果

基本上的用法就這些。