首頁 > 軟體

Spring超詳細講解事務

2022-07-12 14:00:03

什麼是事務

一個資料庫事務是一個被視為一個工作單元的邏輯上的一組操作,這些操作要麼全部執行,要麼全部不執行。

需要注意的是,並不是所有的資料庫(引擎)都支援事務,比如說MySQL的MyISAM儲存引擎

事務的四個特性(ACID)

原子性:事務是一個原子性操作,一個事務由一系列操作組成,這一系列操作要麼全部執行完成,要麼全部不執行

一致性:一個事務執行完成(不管成功還是失敗),資料庫的完整性不能被破壞(唯一約束,外來鍵約束等)

隔離性:資料庫允許多個並行事務同時對資料進行讀寫操作,隔離性可以防止這些操作同時執行時導致的資料不一致的問題。事務分為不同的隔離級別:讀未提交(read uncommitted)、讀已提交(read committed)、可重複讀(repeatable read)和序列化(Serializable)

永續性:永續性意味著事務完成之後,該事物對資料的更改會永久的儲存在資料庫中。

Spring對事務的支援

Spring支援程式設計式事務管理和宣告式事務管理兩種型別的事務管理。

程式設計式事務管理比較靈活,但是很難維護,平時用的很少。

宣告式事務管理易用性更高,侵入性、耦合度低,更推薦使用。

程式設計式事務管理

使用TransactionTemplate進行程式設計式事務管理

    @Autowired
    TransactionTemplate transactionTemplate;
    public void doTest() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                try {
                    // 業務程式碼
                    userMapper.deleteById(200106);
                    int i = 10/0;
                } catch (Exception e) {
                    transactionStatus.setRollbackOnly();
                }
            }
        });
    }

使用PlatformTransactionManager進行程式設計式事務管理

    @Autowired
    PlatformTransactionManager platformTransactionManager;
    public void doTest() {
        TransactionStatus transaction = platformTransactionManager.getTransaction(new DefaultTransactionDefinition());
        try{
            // 業務程式碼
            userMapper.deleteById(200106);
            int i = 10/0;
            platformTransactionManager.commit(transaction);
        }catch (Exception e){
            platformTransactionManager.rollback(transaction);
        }
    }

宣告式事務管理

Spring主要通過兩種方式實現宣告式事務管理:

基於註解的宣告式事務管理

基於XML的宣告式事務管理

基於註解的宣告式事務管理

註解的事務管理主要靠@Transactional註解來實現的。

@Transactional註解可以作用於類或方法上,作用於類上時,該類的所有public方法都具有該事物屬性

@Transactional註解只應該被應用到public修飾的方法上,這是有Spring AOP的本質決定的

    @Transactional
    public void doTest() {
        userMapper.deleteById(200106);
        int i = 10/0;
    }

@Transactional註解

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
	// 指定事務管理器
	@AliasFor("transactionManager")
	String value() default "";
	@AliasFor("value")
	String transactionManager() default "";
	// 事務的傳播行為(enum)
	Propagation propagation() default Propagation.REQUIRED;
	// 事務的隔離級別(enum)
	Isolation isolation() default Isolation.DEFAULT;
	// 事務超時時間
	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
	// 讀寫或唯讀事務,預設讀寫事務
	boolean readOnly() default false;
	// 導致事務回滾的異常類
	Class<? extends Throwable>[] rollbackFor() default {};
	// 導致事務回滾的異常類名
    // noRollbackForClassName = {"ArithmeticException"} 
	String[] rollbackForClassName() default {};
	// 不會導致事務回滾的異常類
	Class<? extends Throwable>[] noRollbackFor() default {};
	// 不會導致事務回滾的異常類名
	String[] noRollbackForClassName() default {};
}

Spring事務管理的三個介面

Spring對事務的操作主要通過PlatformTransactionManager介面,通過這個介面,Spring為各大平臺提供了對應的事務管理器,如 JDBC(org.springframework.jdbc.datasource.DataSourceTransactionManager )等。

在Spring框架中,事務管理相關的最重要的三個介面如下:

PlatformTransactionManager

public interface PlatformTransactionManager extends TransactionManager {
    // 根據指定的傳播行為,該方法返回當前活動事務或建立一個新的事務
	TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
			throws TransactionException;
    // 提交指定的事務和關於它的狀態
	void commit(TransactionStatus status) throws TransactionException;
	// 回滾事務
	void rollback(TransactionStatus status) throws TransactionException;
}

TransactionDefinition

public interface TransactionDefinition {
    // …………
    // 返回傳播行為
	default int getPropagationBehavior() {
		return PROPAGATION_REQUIRED;
	}
    // 返回該事務隔離級別
	default int getIsolationLevel() {
		return ISOLATION_DEFAULT;
	}
    // 返回超時時間
	default int getTimeout() {
		return TIMEOUT_DEFAULT;
	}
    // 返回是否唯讀
	default boolean isReadOnly() {
		return false;
	}
    // 返回事務名稱
	@Nullable
	default String getName() {
		return null;
	}
	static TransactionDefinition withDefaults() {
		return StaticTransactionDefinition.INSTANCE;
	}
}

TransactionStatus

public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
	boolean hasSavepoint();
	@Override
	void flush();
}

Spring事務屬性

Spring事務管理的五大屬性:隔離級別、傳播行為、超時時間、是否唯讀、回滾規則

TransactionDefinition介面中定義了事務的隔離級別、傳播行為、超時時間的常數

public interface TransactionDefinition {
    // 當前存在事務,則加入該事務;如果當前沒有事務,則建立一個新的事務
	int PROPAGATION_REQUIRED = 0;
    // ~,~,~,則繼續以非事務的方式執行
	int PROPAGATION_SUPPORTS = 1;
    // ~,~,~,則丟擲異常
	int PROPAGATION_MANDATORY = 2;
    // 建立一個新事務,如果當前存在事務,則把當前事務掛起
	int PROPAGATION_REQUIRES_NEW = 3;
    // 以非事務的方式執行,如果當前存在事務,則把當前事務掛起
	int PROPAGATION_NOT_SUPPORTED = 4;
    // 以非事務的方式執行,如果當前存在事務,則丟擲異常
	int PROPAGATION_NEVER = 5;
    // ~,則建立一個事務作為當前事務的巢狀事務來執行,~,則等價於PROPAGATION_REQUIRED
	int PROPAGATION_NESTED = 6;
    // 預設的隔離級別
	int ISOLATION_DEFAULT = -1;
    // 讀未提交
	int ISOLATION_READ_UNCOMMITTED = 1; 
    // 讀已提交
	int ISOLATION_READ_COMMITTED = 2;  
    // 可重複讀
	int ISOLATION_REPEATABLE_READ = 4; 
    // 序列化讀
	int ISOLATION_SERIALIZABLE = 8; 
    // 預設的超時時間,單位:秒
    // 所謂事務超時,就是規定一個事務允許執行的最長時間,如果超過了該時間事務還沒有執行完成,則回滾事務。
	int TIMEOUT_DEFAULT = -1;
	default int getPropagationBehavior() {
		return PROPAGATION_REQUIRED;
	}
	default int getIsolationLevel() {
		return ISOLATION_DEFAULT;
	}
	default int getTimeout() {
		return TIMEOUT_DEFAULT;
	}
	default boolean isReadOnly() {
		return false;
	}
	@Nullable
	default String getName() {
		return null;
	}
	static TransactionDefinition withDefaults() {
		return StaticTransactionDefinition.INSTANCE;
	}
}

是否唯讀:指該事物是唯讀操作還是讀寫操作,boolean型別

回滾規則:我們可以人為的控制事務在執行過程中丟擲某些異常時仍然提交事務,或者丟擲某些異常時回滾事務

到此這篇關於Spring超詳細講解事務的文章就介紹到這了,更多相關Spring事務內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com