中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

spring框架入門之什么是事務控制

發布時間:2021-10-28 15:36:50 來源:億速云 閱讀:119 作者:iii 欄目:編程語言

本篇內容主要講解“spring框架入門之什么是事務控制”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“spring框架入門之什么是事務控制”吧!

1. 關于事務控制

事務是一系列的動作,它們綜合在一起才是一個完整的工作單元,這些動作必須全部完成,如果有一個失敗的話,那么事務就會回滾到最開始的狀態,仿佛什么都沒發生過一樣。

1.1 spring中事務控制API

PlatformTransactionManager 接口提供事務操作的方法,包含三個具體的操作

public interface PlatformTransactionManager extends TransactionManager {
    // 獲取事務狀態信息
    TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;

    // 提交事務
    void commit(TransactionStatus var1) throws TransactionException;

    // 回滾事務
    void rollback(TransactionStatus var1) throws TransactionException;
}

開發中常用的實現類:

org.springframework.jdbc.datasource.DataSourceTransactionManager :使用Spring JDBC或iBatis進行持久化數據時使用

spring中事務控制接口的結構

spring框架入門之什么是事務控制

1.1.2 TransactionDefinition

事務的定義信息對象,包含如下方法:

獲取事務對象名稱:String getName()

獲取事務隔離級別:int getIsolationLevel()

獲取事務傳播行為:int getPropagationBehavior()

獲取事務超時時間:int getTimeout()

獲取事務是否只讀:boolean isReadOnly()

1.1.3 TransactionStatus

描述了某個時間點上事務對象的狀態信息,包含6個具體的操作:

刷新事務:void flush()

獲取是否存在儲存點:boolean hasSavepoint()

獲取事務是否完成:boolean isCompleted()

獲取事務是否為新的事物:boolean isNewTransaction()

獲取事務是否回滾:boolean isRollbackOnly()

設置事務回滾:void set RollbackOnly()

1.2 事務的隔離級別

事務的隔離界別反映事務提交并發訪問時的處理態度

1.2.1 事務隔離的級別

ISOLATION_DEFAULT 默認級別,由 DBA 默認的設置來決定隔離級別,歸屬下列某一種

ISOLATION_READ_UNCOMMITTED 就是一個事務可以讀取另一個未提交事務的數據。會出現臟讀、不可重復讀、幻讀(隔離級別最低,但并發性高)

ISOLATION_READ_COMMITTED 就是一個事務要等另一個事務提交后才能讀取數據,解決臟讀問題。會出現不可重復讀、幻讀問題(鎖定正在讀取的行,適用于大多數系統,Oracle默認級別)

ISOLATION_REPEATABLE_READ 就是在開始讀取數據(事務開啟)時,不再允許修改操作,解決不可重復讀問題。會出現幻讀問題(鎖定所讀的所有行,MYSQL默認級別)

ISOLATION_SERALZABLE 是最高的事務隔離級別,在該級別下,事務串行化順序執行,可以避免臟讀、不可重復讀與幻讀。但是這種事務隔離級別效率低下,比較耗數據庫性能,一般不使用。(鎖整表)

事務隔離級別由上到下依次提升,隔離級別越高,越能保證數據的完整性和一致性。但對數據庫性能的消耗依次增加,并發執行效率依次下降。

大多數的數據庫默認隔離級別為 Read Commited,比如 SqlServer、Oracle

少數數據庫默認隔離級別為:Repeatable Read 比如:MySQL InnoDB

1.2.2 數據庫讀取時會出現的三種問題

Dirty reads:讀臟數據。

也就是說,比如事務A的未提交(還依然緩存)的數據被事務B讀走,如果事務A失敗回滾,會導致事務B所讀取的的數據是錯誤的。

non-repeatable reads:數據不可重復讀。

比如事務A中兩處讀取數據price的值。在第一讀的時候,price是100,然后事務B就把price的值改成 200;事務A再讀一次,結果就發現,price竟然就變成200了,造成事務A數據混亂。

phantom reads:幻象讀數據。

這個和non-repeatable reads相似,也是同一個事務中多次讀不一致的問題。但是 non-repeatable reads 的不一致是因為他所要取的數據值被改變了(比如price)而 phantom reads 所要讀的數據的不一致卻是他的條件數據集發生變化了。

比如:執行 Select account.id where account.name="Bruce*",第一次讀去了6個符合條件的id;第二次讀取的時候,由于事務B把一個帳號的名字由"dd"改成"Bruce1",結果取出來了7個數據。

不可重復讀的重點是修改:同樣的條件,兩次讀發現值不一樣;

幻讀的重點在于新增或者刪除:同樣的條件,兩次讀發現得到的記錄數不一樣

1.2.3 數據隔離級別和出現的問題之間的關聯


Dirty readsnon-repeatable readsphantom reads
READ_UNCOMMITTEDYYY
READ_COMMITTEDNYY
REPEATABLE_READNNY
SERALZABLENNN
1.3 事務的傳播行為
  • REQUIRED:如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。一般的選 擇(默認值)

  • SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行(沒有事務)

  • MANDATORY:使用當前的事務,如果當前沒有事務,就拋出異常。

  • REQUERS_NEW:新建事務,如果當前在事務中,把當前事務掛起。

  • NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

  • NEVER:以非事務方式運行,如果當前存在事務,拋出異常。

  • NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行REQUIRED類似的操作。

1.4 超時時間

指事務提交后最長可以等待的時間,超出時間則會自動失敗。默認值是-1,沒有時間限制。如果有,則以秒為單位進行設置。

1.5 是否為只讀事務

讀寫型事務:增加、刪除、修改時開啟事務

只讀型事務:執行查詢時,也會開啟事務

2. 基于xml的事務控制配置

2.1 配置步驟
  1. 配置事務管理器

  2. 配置事務的通知

    此時我們需要導入事務的約束 tx名稱空間和約束,同時也需要aop的使用 <tx:advice> 標簽配置事務通知

    • id:給事務通知起一個唯一標識

    • transaction-manager:給事務通知提供一個事務管理器引用

  3. 配置AOP中的通用切入點表達式

  4. 建立事務通知和切入點表達式的對應關系

  5. 配置事務的屬性是在事務的通知 <tx:advice> 標簽的內部

2.2 配置事務的屬性
  • isolation:用于指定事務的隔離級別。默認值是 DEFAULT,表示使用數據庫的默認隔離級別。

  • propagation:用于指定事務的傳播行為。默認值是 REQUIRED,表示一定會有事務,增刪改的選擇。查詢方法可以選擇 SUPPORTS

  • read-only:用于指定事務是否只讀。只有查詢方法才能設置為 true。默認值是false,表示讀寫。

  • timeout:用于指定事務的超時時間,默認值是-1,表示永不超時。如果指定了數值,以秒為單位。

  • rollback-for:用于指定一個異常,當產生該異常時,事務回滾,產生其他異常時,事務不回滾。沒有默認值。表示任何異常都回滾。

  • no-rollback-for:用于指定一個異常,當產生該異常時,事務不回滾,產生其他異常時事務回滾。沒有默認值。表示任何異常都回滾。

代碼示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 配置數據源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/base_crud"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

    <!-- 1.配置事務管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 2.配置事務通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" read-only="false"></tx:method>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"></tx:method>
        </tx:attributes>
    </tx:advice>

    <!-- 3.配置AOP -->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* cn.bruce.service.impl.*.*(..))"/>
	<!-- 4.建立事務通知和切入點表達式的對應關系 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
    </aop:config>

    <!-- 配置dao -->
    <bean id="accountDao" class="cn.bruce.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置service -->
    <bean id="accountService" class="cn.bruce.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>

</beans>

3. 基于注解的事務控制配置

3.1 配置步驟

① 書寫配置類

② 將對象注入到IoC容器中管理

③ 給業務添加事務注釋,并指明事務屬性

代碼示例:

① 配置spring

@Configuration// 聲明為配置類
@ComponentScan("cn.bruce")// 聲明需要掃描的包
@Import({JdbcConfig.class, TransactionConfig.class})// 導入其他配置類
@PropertySource("jdbcConfig.properties")// 導入配置文件
@EnableAspectJAutoProxy(proxyTargetClass = true)// 開啟注解支持
@EnableTransactionManagement// 開啟事務控制
public class SpringConfiguration {
}

② 配置jdbc

public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    /**
     * 創建數據源對象
     * @return
     */
    @Bean("dataSource")
    public DataSource creatDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    /**
     * 創建JdbcTemplate
     * @param dataSource
     * @return
     */
    @Bean(name = "jdbcTemplate")
    public JdbcTemplate creatJdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

③ 配置事務控制器

public class TransactionConfig {

    /**
     * 用于創建事務管理器對象
     * @param dataSource
     * @return
     */
    @Bean(name = "transactionManager")
    public PlatformTransactionManager creatTransactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

④ 通過 [@Repository](https://my.oschina.net/u/3055569)[@service](https://my.oschina.net/service) 注解將Dao和Service層對象注入IoC容器

⑤ 在業務層使用 [@Transactional](https://my.oschina.net/u/3770144) 注解進行事務配置

// 進行讀寫型事務配置
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
@Override
public void transfer(String sourceName, String targetName, Float money) {

    System.out.println("開始進行轉賬操作。。。");

    Account source = accountDao.getAccountByName(sourceName);

    Account target = accountDao.getAccountByName(targetName);

    source.setMoney(source.getMoney() - money);

    target.setMoney(target.getMoney() + money);

    accountDao.updateAccount(source);

    int i = 1/0;

    accountDao.updateAccount(target);

    System.out.println("轉賬完成。。。");
}

⑥ 書寫測試類進行測試

3.2 涉及到的注解

[@Transactional](https://my.oschina.net/u/3770144) 此注解相當于xml配置中的 <tx:attributes>****</tx:attributes> 用于進行事務的配置,其屬性含義和xml中是一致的

此注解可是使用在接口、類和方法上:

  • 出現在接口上,表示此接口所有的實現類都有事務支持

  • 出現在類上,表示類所有的方法都有事務支持

  • 出現在方法上,表示此方法有事務支持

  • 以上三個位置的優先級:方法 > 類 > 接口

到此,相信大家對“spring框架入門之什么是事務控制”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

无极县| 玛多县| 凉山| 枝江市| 绿春县| 襄汾县| 新河县| 饶阳县| 河西区| 凭祥市| 开原市| 贵州省| 平南县| 米泉市| 马鞍山市| 东乌珠穆沁旗| 泸西县| 涞水县| 孙吴县| 遂宁市| 福贡县| 且末县| 黎城县| 石台县| 兖州市| 刚察县| 山阴县| 河北区| 陇南市| 夹江县| 雷波县| 蓬溪县| 枣庄市| 长乐市| 霍州市| 永登县| 宝兴县| 厦门市| 肃宁县| 峨眉山市| 宿迁市|