Spring超詳細(xì)講解事務(wù)
什么是事務(wù)
一個(gè)數(shù)據(jù)庫(kù)事務(wù)是一個(gè)被視為一個(gè)工作單元的邏輯上的一組操作,這些操作要么全部執(zhí)行,要么全部不執(zhí)行。
需要注意的是,并不是所有的數(shù)據(jù)庫(kù)(引擎)都支持事務(wù),比如說(shuō)MySQL的MyISAM存儲(chǔ)引擎
事務(wù)的四個(gè)特性(ACID)
原子性:事務(wù)是一個(gè)原子性操作,一個(gè)事務(wù)由一系列操作組成,這一系列操作要么全部執(zhí)行完成,要么全部不執(zhí)行
一致性:一個(gè)事務(wù)執(zhí)行完成(不管成功還是失?。瑪?shù)據(jù)庫(kù)的完整性不能被破壞(唯一約束,外鍵約束等)
隔離性:數(shù)據(jù)庫(kù)允許多個(gè)并發(fā)事務(wù)同時(shí)對(duì)數(shù)據(jù)進(jìn)行讀寫(xiě)操作,隔離性可以防止這些操作同時(shí)執(zhí)行時(shí)導(dǎo)致的數(shù)據(jù)不一致的問(wèn)題。事務(wù)分為不同的隔離級(jí)別:讀未提交(read uncommitted)、讀已提交(read committed)、可重復(fù)讀(repeatable read)和串行化(Serializable)
持久性:持久性意味著事務(wù)完成之后,該事物對(duì)數(shù)據(jù)的更改會(huì)永久的保存在數(shù)據(jù)庫(kù)中。
Spring對(duì)事務(wù)的支持
Spring支持編程式事務(wù)管理和聲明式事務(wù)管理兩種類(lèi)型的事務(wù)管理。
編程式事務(wù)管理比較靈活,但是很難維護(hù),平時(shí)用的很少。
聲明式事務(wù)管理易用性更高,侵入性、耦合度低,更推薦使用。
編程式事務(wù)管理
使用TransactionTemplate進(jìn)行編程式事務(wù)管理
@Autowired
TransactionTemplate transactionTemplate;
public void doTest() {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
try {
// 業(yè)務(wù)代碼
userMapper.deleteById(200106);
int i = 10/0;
} catch (Exception e) {
transactionStatus.setRollbackOnly();
}
}
});
}
使用PlatformTransactionManager進(jìn)行編程式事務(wù)管理
@Autowired
PlatformTransactionManager platformTransactionManager;
public void doTest() {
TransactionStatus transaction = platformTransactionManager.getTransaction(new DefaultTransactionDefinition());
try{
// 業(yè)務(wù)代碼
userMapper.deleteById(200106);
int i = 10/0;
platformTransactionManager.commit(transaction);
}catch (Exception e){
platformTransactionManager.rollback(transaction);
}
}
聲明式事務(wù)管理
Spring主要通過(guò)兩種方式實(shí)現(xiàn)聲明式事務(wù)管理:
基于注解的聲明式事務(wù)管理
基于XML的聲明式事務(wù)管理
基于注解的聲明式事務(wù)管理
注解的事務(wù)管理主要靠@Transactional注解來(lái)實(shí)現(xiàn)的。
@Transactional注解可以作用于類(lèi)或方法上,作用于類(lèi)上時(shí),該類(lèi)的所有public方法都具有該事物屬性
@Transactional注解只應(yīng)該被應(yīng)用到public修飾的方法上,這是有Spring AOP的本質(zhì)決定的
@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 {
// 指定事務(wù)管理器
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
// 事務(wù)的傳播行為(enum)
Propagation propagation() default Propagation.REQUIRED;
// 事務(wù)的隔離級(jí)別(enum)
Isolation isolation() default Isolation.DEFAULT;
// 事務(wù)超時(shí)時(shí)間
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
// 讀寫(xiě)或只讀事務(wù),默認(rèn)讀寫(xiě)事務(wù)
boolean readOnly() default false;
// 導(dǎo)致事務(wù)回滾的異常類(lèi)
Class<? extends Throwable>[] rollbackFor() default {};
// 導(dǎo)致事務(wù)回滾的異常類(lèi)名
// noRollbackForClassName = {"ArithmeticException"}
String[] rollbackForClassName() default {};
// 不會(huì)導(dǎo)致事務(wù)回滾的異常類(lèi)
Class<? extends Throwable>[] noRollbackFor() default {};
// 不會(huì)導(dǎo)致事務(wù)回滾的異常類(lèi)名
String[] noRollbackForClassName() default {};
}
Spring事務(wù)管理的三個(gè)接口
Spring對(duì)事務(wù)的操作主要通過(guò)PlatformTransactionManager接口,通過(guò)這個(gè)接口,Spring為各大平臺(tái)提供了對(duì)應(yīng)的事務(wù)管理器,如 JDBC(org.springframework.jdbc.datasource.DataSourceTransactionManager )等。
在Spring框架中,事務(wù)管理相關(guān)的最重要的三個(gè)接口如下:
PlatformTransactionManager
public interface PlatformTransactionManager extends TransactionManager {
// 根據(jù)指定的傳播行為,該方法返回當(dāng)前活動(dòng)事務(wù)或創(chuàng)建一個(gè)新的事務(wù)
TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException;
// 提交指定的事務(wù)和關(guān)于它的狀態(tài)
void commit(TransactionStatus status) throws TransactionException;
// 回滾事務(wù)
void rollback(TransactionStatus status) throws TransactionException;
}TransactionDefinition
public interface TransactionDefinition {
// …………
// 返回傳播行為
default int getPropagationBehavior() {
return PROPAGATION_REQUIRED;
}
// 返回該事務(wù)隔離級(jí)別
default int getIsolationLevel() {
return ISOLATION_DEFAULT;
}
// 返回超時(shí)時(shí)間
default int getTimeout() {
return TIMEOUT_DEFAULT;
}
// 返回是否只讀
default boolean isReadOnly() {
return false;
}
// 返回事務(wù)名稱
@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事務(wù)屬性
Spring事務(wù)管理的五大屬性:隔離級(jí)別、傳播行為、超時(shí)時(shí)間、是否只讀、回滾規(guī)則
在TransactionDefinition接口中定義了事務(wù)的隔離級(jí)別、傳播行為、超時(shí)時(shí)間的常量
public interface TransactionDefinition {
// 當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒(méi)有事務(wù),則創(chuàng)建一個(gè)新的事務(wù)
int PROPAGATION_REQUIRED = 0;
// ~,~,~,則繼續(xù)以非事務(wù)的方式運(yùn)行
int PROPAGATION_SUPPORTS = 1;
// ~,~,~,則拋出異常
int PROPAGATION_MANDATORY = 2;
// 創(chuàng)建一個(gè)新事務(wù),如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起
int PROPAGATION_REQUIRES_NEW = 3;
// 以非事務(wù)的方式運(yùn)行,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起
int PROPAGATION_NOT_SUPPORTED = 4;
// 以非事務(wù)的方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異常
int PROPAGATION_NEVER = 5;
// ~,則創(chuàng)建一個(gè)事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來(lái)運(yùn)行,~,則等價(jià)于PROPAGATION_REQUIRED
int PROPAGATION_NESTED = 6;
// 默認(rèn)的隔離級(jí)別
int ISOLATION_DEFAULT = -1;
// 讀未提交
int ISOLATION_READ_UNCOMMITTED = 1;
// 讀已提交
int ISOLATION_READ_COMMITTED = 2;
// 可重復(fù)讀
int ISOLATION_REPEATABLE_READ = 4;
// 序列化讀
int ISOLATION_SERIALIZABLE = 8;
// 默認(rèn)的超時(shí)時(shí)間,單位:秒
// 所謂事務(wù)超時(shí),就是規(guī)定一個(gè)事務(wù)允許執(zhí)行的最長(zhǎng)時(shí)間,如果超過(guò)了該時(shí)間事務(wù)還沒(méi)有執(zhí)行完成,則回滾事務(wù)。
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;
}
}是否只讀:指該事物是只讀操作還是讀寫(xiě)操作,boolean類(lèi)型
回滾規(guī)則:我們可以人為的控制事務(wù)在執(zhí)行過(guò)程中拋出某些異常時(shí)仍然提交事務(wù),或者拋出某些異常時(shí)回滾事務(wù)
到此這篇關(guān)于Spring超詳細(xì)講解事務(wù)的文章就介紹到這了,更多相關(guān)Spring事務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java線程監(jiān)聽(tīng),意外退出線程后自動(dòng)重啟的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇Java線程監(jiān)聽(tīng),意外退出線程后自動(dòng)重啟的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
SpringBoot整合Spring Security構(gòu)建安全的Web應(yīng)用
pring Security是一個(gè)強(qiáng)大的身份驗(yàn)證和訪問(wèn)控制框架,本文主要介紹了SpringBoot整合Spring Security構(gòu)建安全的Web應(yīng)用,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
elasticsearch節(jié)點(diǎn)的transport請(qǐng)求發(fā)送處理分析
這篇文章主要為大家介紹了elasticsearch節(jié)點(diǎn)的transport請(qǐng)求發(fā)送處理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
Java中JMM與volatile關(guān)鍵字的學(xué)習(xí)
這篇文章主要介紹了通過(guò)實(shí)例解析JMM和Volatile關(guān)鍵字的學(xué)習(xí),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-09-09
Java基礎(chǔ)之Comparable與Comparator概述
這篇文章主要介紹了Java基礎(chǔ)之Comparable與Comparator詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
spring boot攔截器注入不了java bean的原因
這篇文章主要介紹了spring boot攔截器注入不了java bean的原因,幫助大家更好的理解和學(xué)習(xí)spring boot框架,感興趣的朋友可以了解下2020-11-11
Java中List轉(zhuǎn)Map的幾種常見(jiàn)方式與對(duì)比
JavaList轉(zhuǎn)Map是一個(gè)非常常用的技術(shù),對(duì)于Java開(kāi)發(fā)人員來(lái)講,掌握該技術(shù)可以幫助我們更加高效地操作List集合中的對(duì)象,這篇文章主要給大家介紹了關(guān)于Java中List轉(zhuǎn)Map的幾種常見(jiàn)方式與對(duì)比的相關(guān)資料,需要的朋友可以參考下2024-02-02
Springboot登錄驗(yàn)證的統(tǒng)一攔截處理的實(shí)現(xiàn)
如果不進(jìn)行統(tǒng)一的攔截處理,每次用戶請(qǐng)求你都要去進(jìn)行用戶的信息驗(yàn)證,所以本文主要介紹了Springboot登錄驗(yàn)證的統(tǒng)一攔截處理的實(shí)現(xiàn),感興趣的可以了解一下,感興趣的可以了解一下2023-09-09

