第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Spring 的聲明式事務(wù)控制

1. 前言

各位同學(xué)大家好,long time no see.

本小節(jié),我給大家?guī)?lái) Spring 對(duì)于事務(wù)的另外一種支持方式,也就是聲明式事務(wù)的配置。其實(shí)聲明式配置和 xml 文件的配置,孰優(yōu)孰劣并不是重點(diǎn)。

Spring 框架設(shè)計(jì)兩種模式的初衷更多是體現(xiàn)技術(shù)的多樣性,畢竟條條大路通羅馬。您說呢?所以本小節(jié)重點(diǎn)就看如果使用注解來(lái)對(duì)事務(wù)做支持,那么我們應(yīng)該如何做,又有哪些需要注意點(diǎn)地方。

各位看官,隨我來(lái),不要掉隊(duì)哦…

課程回顧

老套路,首先我們回顧一下 xml 對(duì)于事務(wù)支持的實(shí)現(xiàn):

1. 在 Spring 的 xml 配置文件中,使用 bean 標(biāo)簽初始化配置事務(wù)的管理器類 DataSourceTransactionManager;

2. 在 Spring 的 xml 配置文件中,通過 tx:advice 節(jié)點(diǎn)配置事務(wù)使用的通知方式,已經(jīng)支持的事務(wù)級(jí)別;

3. 在 Spring 的 xml 配置文件中,通過 aop:config 節(jié)點(diǎn)指定切入點(diǎn),說明哪些類的哪些方法需要支持事務(wù),同時(shí)將配置的切入點(diǎn)和通知整合到一起。

xml 的方式回顧之后,就看我們使用注解如何替換掉上面的必要配置吧…

2. 實(shí)例演示

2.1 工程搭建

1. 創(chuàng)建工程
圖片描述
2. 引入依賴

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
		<!-- Spring jdbc 使用的依賴-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
     	<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.7</version>
   		 </dependency>
    </dependencies>

3. 準(zhǔn)備代碼
實(shí)體類代碼

/**
 * 賬戶的實(shí)體類
 */
public class Account implements Serializable {
    //數(shù)據(jù)id
    private Integer id;
    //賬號(hào)編碼
    private String accountNum;
    //賬號(hào)金額
    private Float money;
}

持久層接口代碼

/**
 * 賬戶的持久層接口
 */
public interface IAccountDao {

    /**
     * 根據(jù)Id查詢賬戶
     * @param accountId
     * @return
     */
    Account findAccountById(Integer accountId);

    /**
     * 保存賬戶
     * @param account
     */
    void saveAccount(Account account);

    /**
     * 更新賬戶
     * @param account
     */
    void updateAccount(Account account);


}

持久層實(shí)現(xiàn)類代碼

/**
 * 賬戶的持久層實(shí)現(xiàn)類
 */
@Repository
public class AccountDaoImpl implements IAccountDao {
    //jdbc模板類屬性
    @Autowired
    private JdbcTemplate jdbcTemplate;

    //根據(jù)id查找
    public Account findAccountById(Integer accountId) {
        List<Account> accounts = jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
        return accounts.isEmpty()?null:accounts.get(0);
    }

    public void saveAccount(Account account) {
        jdbcTemplate.update("insert into account  values(?,?,?)",
                account.getId(),account.getAccountNum(),account.getMoney());
    }

    public void updateAccount(Account account) {
        jdbcTemplate.update("update account set accountnum=?,money=? where id=?",account.getAccountNum(),account.getMoney(),account.getId());
    }
}

業(yè)務(wù)層接口代碼

/**
 * @Auther: wyan
 */
public interface UserService {

    /**
     * 賬戶轉(zhuǎn)賬
     * @param fromId toId
     */
    public void transMoney(Integer fromId, Integer toId, Integer money);

}

業(yè)務(wù)層實(shí)現(xiàn)類代碼

/**
 * @Auther: wyan
 * @Description:
 */
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private IAccountDao accountDao;

    public void transMoney(Integer fromId, Integer toId, Integer money) {
        Account fromAccount = accountDao.findAccountById(fromId);
        Account toAccount = accountDao.findAccountById(toId);
        //原始賬號(hào)減錢
        fromAccount.setMoney(fromAccount.getMoney()-money);
        accountDao.updateAccount(fromAccount);
        //拋出異常
        int i=1/0;
        //轉(zhuǎn)賬賬號(hào)加錢
        toAccount.setMoney(toAccount.getMoney()+money);
        accountDao.updateAccount(toAccount);
    }
}

Tips: 此時(shí)需要注意注解 @Transactional 的含義。

Transactional 就是表示事務(wù),那么在此類上面加入注解,說明需要 Spring 框架針對(duì)此類的方法做事務(wù)的增強(qiáng)行為,也就是說此注解其實(shí)是相當(dāng)于我們?cè)谂渲梦募信渲玫墓?jié)點(diǎn) tx:advice。

那么這時(shí)候有的細(xì)心的同學(xué)可能會(huì)有些疑問:

  1. 我們?cè)?xml 文件中可以配置事務(wù)的傳播行為與隔離級(jí)別,那么這一個(gè)注解如何制定事務(wù)的傳播行為與隔離級(jí)別呢?
  2. 一個(gè)類中如果定義方法過多,而實(shí)際上需要增強(qiáng)控制事務(wù)的方法只有一部分,如何縮小粒度,只控制需要事務(wù)的方法呢?

ok,大家。這里有必要跟大家解釋下此注解的其余使用方式:

問題一答疑

在注解后面可以通過括號(hào)內(nèi)的參數(shù)設(shè)置隔離級(jí)別與傳播行為。比如:

@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED) 此表達(dá)式的含義是事務(wù)一定需要,并且是讀已提交。

問題二答疑:

在方法上使用注解。類上面可以不使用 @Transactional 注解,而是將注解寫在需要用到事務(wù)的方法之上。

4. 配置文件

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--配置JdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置數(shù)據(jù)源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql:///transmoney"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    <!--包路徑掃描-->
    <context:component-scan base-package="com.offcn"></context:component-scan>
    <!--事務(wù)管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 配置數(shù)據(jù)源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql:///transmoney"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    <!--包路徑掃描-->
    <context:component-scan base-package="com.offcn"></context:component-scan>
    <!--事務(wù)管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--注解事務(wù)驅(qū)動(dòng)-->
    <tx:annotation-driven/>

</beans>

Tips: 此處需要注意 tx:annotation-driven 節(jié)點(diǎn)

無(wú)需配置通知節(jié)點(diǎn)與切面節(jié)點(diǎn),而是使用 tx:annotation-driven 節(jié)點(diǎn)表示,事務(wù)的支持方式為聲明式事務(wù)。

5. 測(cè)試代碼

public class AccountServiceTest {

    public static void main(String[] args) {
        //1.獲取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.獲取業(yè)務(wù)對(duì)象
        UserService userService = ac.getBean(UserService.class);
        //3.從id為1的賬號(hào)轉(zhuǎn)成1000到2賬號(hào)
        userService.transMoney(1,2,1000);
        System.out.println("轉(zhuǎn)賬完成..");
    }
}

6. 測(cè)試結(jié)果:
圖片描述
ok, 大家,我們繼續(xù)測(cè)試之前的轉(zhuǎn)賬代碼,依然得到錯(cuò)誤的異常信息。同時(shí)數(shù)據(jù)庫(kù)的金額并沒有發(fā)生改變,因?yàn)槭聞?wù)的控制,保證了數(shù)據(jù)的一致性原子性。那么也證明我們聲明式事務(wù)的案例測(cè)試成功。

3. 總結(jié)

Spring 的聲明式事務(wù),我們今天就到這里。通過本小節(jié),我們知道聲明式事務(wù)實(shí)現(xiàn)一樣很簡(jiǎn)單:

  1. xml 文件中開啟注解驅(qū)動(dòng) tx:annotation-driven;
  2. 在實(shí)現(xiàn)類上使用 @Transactional 注解。

上面兩個(gè)步驟即可實(shí)現(xiàn)聲明式事務(wù)的控制,配置更為簡(jiǎn)潔,代碼可讀性也更強(qiáng)。你學(xué)會(huì)了嗎?

如果你問我,什么是達(dá)到成功最有效的方法,我會(huì)告訴你 —— 堅(jiān)持!