目錄
一、事務(wù)的相關(guān)配置
1. 添加測試標(biāo)簽
2. 添加對應(yīng)方法
3. 測試
二、事務(wù)的傳播行為
三、事務(wù)的隔離級別
四、注解配置聲明式事務(wù)
1. 注冊事務(wù)注解驅(qū)動
2. 加上注解
3. 配置類代替xml文件中的注解事務(wù)支持
4. 測試
往期專欄&文章相關(guān)導(dǎo)讀?
1. Maven系列專欄文章
2. Mybatis系列專欄文章
3. Spring系列專欄文章?
一、事務(wù)的相關(guān)配置
1. 添加測試標(biāo)簽
在 <tx:advice> 中可以進行事務(wù)的相關(guān)配置:
<tx:method> 中的屬性:
- name:指定配置的方法。 * 表示所有方法, find* 表示所有以find開頭的方法。
- read-only:是否是只讀事務(wù),只讀事務(wù)不存在數(shù)據(jù)的修改,數(shù)據(jù)庫將會為只讀事務(wù)提供一些
- 優(yōu)化手段,會對性能有一定提升,建議在查詢中開啟只讀事務(wù)。
- timeout:指定超時時間,在限定的時間內(nèi)不能完成所有操作就會拋異常。默認永不超時
- rollback-for:指定某個異常事務(wù)回滾,其他異常不回滾。默認所有異常回滾。
- no-rollback-for:指定某個異常不回滾,其他異?;貪L。默認所有異?;貪L。
- propagation:事務(wù)的傳播行為
- isolation:事務(wù)的隔離級別
添加?<tx:advice>標(biāo)簽
<!-- 進行事務(wù)相關(guān)配置 -->
<tx:advice id = "txAdvice">
<tx:attributes>
<!-- 代表以find開頭的方法 -->
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice>
2. 添加對應(yīng)方法
????????這里我們對查找用戶id的時候進行用戶修改,看看測試的時候是否報異常,因為上面我們已經(jīng)設(shè)置了find方法開頭為只讀事務(wù),不能對數(shù)據(jù)進行修改?
public Account findById(int id){
Account account = accountDao.findById(1);
account.setBalance(1000);
accountDao.update(account);
return accountDao.findById(id);
}
3. 測試
添加測試方法
@Test
public void testFindById(){
Account account = accountService.findById(1);
System.out.println(account);
}
測試結(jié)果
OK,因此我們可以看到確實以find開頭的方法確實是只能讀取,不能修改。?
二、事務(wù)的傳播行為
????????事務(wù)傳播行為是指多個含有事務(wù)的方法相互調(diào)用時,事務(wù)如何在這些方法間傳播。
????????如果在service層的方法中調(diào)用了其他的service方法,假設(shè)每次執(zhí)行service方法都要開啟事務(wù),此時就無法保證外層方法和內(nèi)層方法處于同一個事務(wù)當(dāng)中。例如:
// method1的所有方法在同一個事務(wù)中
public void method1(){
??// 此時會開啟一個新事務(wù),這就無法保證method1()
中所有的代碼是在同一個事務(wù)中
??method2();
??System.out.println("method1");
}
public void method2(){
??System.out.println("method2");
}
????????事務(wù)的傳播特性就是解決這個問題的,Spring幫助我們將外層方法和內(nèi)層方法放入同一事務(wù)中。
傳播行為 | 介紹 |
---|---|
REQUIRED | 默認。支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就新建一個事務(wù)。這是最常見的選擇。 |
SUPPORTS | 支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行。 |
MANDATORY | 支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就拋出異常。 |
REQUIRES_NEW | 新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。 |
NOT_SUPPORTED | 以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。 |
NEVER | 以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常。 |
NESTED | 必須在事務(wù)狀態(tài)下執(zhí)行,如果沒有事務(wù)則新建事務(wù),如果當(dāng)前有事務(wù)則創(chuàng)建一個嵌套事務(wù)? |
三、事務(wù)的隔離級別
????????事務(wù)隔離級別反映事務(wù)提交并發(fā)訪問時的處理態(tài)度,隔離級別越高,數(shù)據(jù)出問題的可能性越低,但效率也會越低。
隔離級別? | 臟讀? | 不可重復(fù)讀? | 幻讀 |
---|---|---|---|
READ_UNCOMMITED(讀取未提交內(nèi)容)? | Yes? | Yes? | Yes? |
READ_COMMITED(讀取提交內(nèi)容)? | No | Yes? | Yes? |
REPEATABLE_READ(重復(fù)讀) | No | No | Yes? |
SERIALIZABLE(可串行化)? | No | No | No |
如果設(shè)置為DEFAULT會使用數(shù)據(jù)庫的隔離級別。
- SqlServer , Oracle默認的事務(wù)隔離級別是READ_COMMITED
- Mysql的默認隔離級別是REPEATABLE_READ
四、注解配置聲明式事務(wù)
Spring支持使用注解配置聲明式事務(wù)。用法如下:
1. 注冊事務(wù)注解驅(qū)動
<!-- 注冊事務(wù)注解驅(qū)動 -->
<tx:annotation-driven transaction-manager="transactionManager">
</tx:annotation-driven>
2. 加上注解
在需要事務(wù)支持的方法或類上加@Transactional注解
package com.example.service;
import com.example.dao.AccountDao;
import com.example.pojo.Account;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
// 作用類上時,該類所有public方法將都具有該類型的事務(wù)屬性
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
public class AccountService {
@Autowired
private AccountDao accountDao;
/**
*
* @param id1 轉(zhuǎn)出人id
* @param id2 轉(zhuǎn)入人id
* @param price 金額
*/
// 作用方法上時,該方法都將具有該類型事務(wù)的事務(wù)屬性
public void transfer(int id1,int id2, double price){
// 轉(zhuǎn)出人減少余額
Account account1 = accountDao.findById(id1);
account1.setBalance(account1.getBalance() - price);
accountDao.update(account1);
// 模擬程序出錯
int i = 1 / 0;
// 轉(zhuǎn)入人增加余額
Account account2 = accountDao.findById(id2);
account2.setBalance(account2.getBalance() + price);
accountDao.update(account2);
}
}
3. 配置類代替xml文件中的注解事務(wù)支持
配置類代替xml中的注解事務(wù)支持:需要在配置類上方寫@EnableTranscationManagement
import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
@Configuration
@ComponentScan("com.example")
@EnableTransactionManagement
public class SpringConfig {
@Bean
public DataSource getDataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
druidDataSource.setUrl("jdbc:mysql:///spring");
druidDataSource.setUsername("root");
druidDataSource.setPassword("666666");
return druidDataSource;
}
@Bean
public SqlSessionFactoryBean getSqlSession(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
@Bean
public MapperScannerConfigurer getMapperScanner(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.example.dao");
return mapperScannerConfigurer;
}
@Bean
public DataSourceTransactionManager getTransactionManger(DataSource dataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
}
4. 測試
添加測試方法
// 測試注解配置類
@Test
public void testSpringConfig(){
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
AccountService service = (AccountService) ac.getBean("accountService");
accountService.transfer(1,2,500);
}
測試結(jié)果
????????OK,可以看到確實出現(xiàn)異常中斷了,因此測試成功,Spring專欄也到此告一段落啦 ,接下來就開啟了SpringMVC框架學(xué)習(xí)。希望大家可以持續(xù)關(guān)注?。。?!文章來源:http://www.zghlxwxcb.cn/news/detail-481739.html
往期專欄&文章相關(guān)導(dǎo)讀?
?????大家如果對于本期內(nèi)容有什么不了解的話也可以去看看往期的內(nèi)容,下面列出了博主往期精心制作的Maven,Mybatis等專欄系列文章,走過路過不要錯過哎!如果對您有所幫助的話就點點贊,收藏一下啪。其中Spring專欄有些正在更,所以無法查看,但是當(dāng)博主全部更完之后就可以看啦。文章來源地址http://www.zghlxwxcb.cn/news/detail-481739.html
1. Maven系列專欄文章
Maven系列專欄 | Maven工程開發(fā) |
Maven聚合開發(fā)【實例詳解---5555字】 |
2. Mybatis系列專欄文章
Mybatis系列專欄 | MyBatis入門配置 |
Mybatis入門案例【超詳細】 | |
MyBatis配置文件 —— 相關(guān)標(biāo)簽詳解 | |
Mybatis模糊查詢——三種定義參數(shù)方法和聚合查詢、主鍵回填 | |
Mybatis動態(tài)SQL查詢 --(附實戰(zhàn)案例--8888個字--88質(zhì)量分) | |
Mybatis分頁查詢——四種傳參方式 | |
Mybatis一級緩存和二級緩存(帶測試方法) | |
Mybatis分解式查詢 | |
Mybatis關(guān)聯(lián)查詢【附實戰(zhàn)案例】 | |
MyBatis注解開發(fā)---實現(xiàn)增刪查改和動態(tài)SQL | |
MyBatis注解開發(fā)---實現(xiàn)自定義映射關(guān)系和關(guān)聯(lián)查詢 |
3. Spring系列專欄文章?
Spring系列專欄 | Spring IOC 入門簡介【自定義容器實例】 |
IOC使用Spring實現(xiàn)附實例詳解 | |
Spring IOC之對象的創(chuàng)建方式、策略及銷毀時機和生命周期且獲取方式 | |
Spring DI簡介及依賴注入方式和依賴注入類型 | |
Spring IOC相關(guān)注解運用——上篇 | |
Spring IOC相關(guān)注解運用——下篇 | |
Spring AOP簡介及相關(guān)案例 | |
注解、原生Spring、SchemaBased三種方式實現(xiàn)AOP【附詳細案例】 | |
Spring事務(wù)簡介及相關(guān)案例 | |
Spring 事務(wù)管理方案和事務(wù)管理器及事務(wù)控制的API | |
Spring 事務(wù)的相關(guān)配置、傳播行為、隔離級別及注解配置聲明式事務(wù) |
到了這里,關(guān)于Spring 事務(wù)的相關(guān)配置、傳播行為、隔離級別及注解配置聲明式事務(wù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!