Hello,你們好,前面兩篇文章給你們分享了Spring AOP,今天就趁熱打鐵,給你們分享一下,Spring中的事務,事務這個事,其實在國內一些小公司,通常都會忽略的,尤爲是不少網站,設計不到錢的系統,不會在意這個東西,事務不回滾形成的結果無非就是髒數據,髒改等後果。由於做者之前待過的一個房產網站,根本就不在意這個事務,有問題就有問題了,反正用戶也沒充錢在網站上。呵呵。今天仍是和你們分享一下這個Spring的事務,由於這個東西算是Spring 內部使用AOP最好的一個體現,體現了AOP思想,OK,文章結構:html
看到Spring boot,不少人確定感受是被忽悠了,爲何說講Spring事務,這又來Spring boot搞事情。用過Spring boot的小夥伴其實都知道,這兩個沒什麼大的區別,筆者這裏使用Spring boot來演示,徹底是爲何了簡便。由於搭一個Spring傳統的ssm三件套工程可能要花費5分鐘,而搭建一個Spring boot的"ssm"工程,就是鼠標點一點的事。並且開啓事務也是一個註解的事。因此,老鐵們,對不住了,這一篇用Spring boot和你們演示Spring的事務,這裏我給一個傳送門,是傳統項目的事務,你們能夠參考下:java
廢話說下,直接上Spring boot代碼:mysql
@SpringBootApplication
@EnableTransactionManagement
public class TestTxApplication {
public static void main(String[] args) {
SpringApplication.run(TestTxApplication.class, args);
}
}
複製代碼
@EnableTransactionManagement 表示開啓事務!spring
@Component
public class PersonService {
@Autowired
private PersonMapper personMapper;
@Transactional
public void testTx(){
//該操做會成功
personMapper.update();
//該操做會報異常
personMapper.update2();
}
}
複製代碼
這是一個Service,內部的personMapper是一個dao接口,持久化用的mybatissql
@Mapper
public interface PersonMapper {
//更改某條記錄
@Update("update user_info set user_name='123' where user_id='1' ")
Long update();
//user_info2這個表不存在。會報異常
@Update("update user_info2 set user_name='123' where user_id='1' ")
Long update2();
}
複製代碼
演示的效果應該是:數據庫
具體我就不演示了 。你們能夠看到,在Spring boot中開啓事務就是一個註解的事 。具體的內部使用什麼trancationManagement根本不用管,Spring boot內部會根據pom中引入的持久層框架自動注入。真是開發神器!數組
而後我說下底層原理:Spring事務其實就是Spring AOP,底層建立動態代理對象,在代碼的開頭結尾封裝了開啓事務和事務回滾操做。用過JDBC原生代碼的更應該清楚了,都是顯示在代理裏commit和rollback的。而後一大堆try catch..mybatis
上面的代碼雖然簡單,也能應對大部分的場景,但仍是有一些問題的,好比,有些異常開發者知道,而且想人爲的控制,"拋出某類異常,不要回滾".這樣的問題。這就引出了,事務屬性這個概念,事務屬性一般由事務的傳播行爲,事務的隔離級別,事務的超時值和事務只讀標誌組成。 這些屬性都是在使用@Transactional能夠指定的,我給一張表格: app
而後把這些屬性講一講:框架
事務的隔離界別:使用@Transactional的Isolation屬性能夠指定事務的隔離級別。但事務的隔離級別是由底層的數據庫實現的,並非由Spring來實現。
通常的數據庫默認提供的是READ_COMMITTED隔離級別,如sqlserver2000;Mysql默認提供的是REPEATABLE_READ;
好了,結論給你們說完了,而後解釋一下上面提到的 髒讀,不可重複讀和幻象讀的概念。
髒讀:
不可重複讀:在一個事務中先後兩次讀取的結果並不致,致使了不可重複讀。
幻想讀:
好了,事務的隔離級別就講完了,通常仍是採用數據庫默認的,像mysql的REPEATABLE_READ,可以避免髒讀和不可重複讀。
其餘的傳播行爲省略,基本不用,通常的傳播行爲也是使用默認的:REQUIRED
Transactional的異常控制,默認是Check Exception不回滾,unCheck Exception回滾,rollbackFor 和noRollbackFor 配置也許不會含蓋全部異常,對於遺漏的按照Check Exception 不回滾,unCheck Exception回滾.
使用@Transactional註解的noRollbackFor和rollbackFor屬性能夠改變默認的行爲:
也可使用noRollbackForClassName、rollbackForClassName屬性來指定一個異常類名的String數組來改變默認的行爲。
好了,事務屬性大體就這麼多了,其餘一些就是比較簡單的了,看名字就知道啥意思,伸手就用的東西,而後再提一下,@Transactional只能被應用到public方法上, 對於其它非public的方法,若是標記了@Transactional也不會報錯,但方法沒有事務功能..
老實說,通常事務屬性配置的比較少,通常都是直接@Transactional加上就完事了。不多配置一些屬性。尤爲是那個事務傳播行爲,在平常的業務裏,不多有食物嵌套的狀況,因此我就是點了一點,沒有展開。通常使用默認就能夠了。
好了,Spring的事務使用層面給你們算是分享完了,在Spring boot裏想使用事務簡單的有點可怕。因此我就採用Spring boot了。其實傳統的SSM項目也很簡單,無非就是在xml文件裏配置下tranclationManagement..而後Spring 事務的底層是Spring AOP,把jdbc的事務代碼嵌入了進去。Over,Have a good day!