首先說下什麼是事物(數據庫):
事物是數據庫中一些列的連續的邏輯操做,事物具備ACID特性。(ACID:原子性、一致性、隔離性、持久性)
在處理平常數據時會出現的三類問題:髒讀、不可重複讀、幻讀。java
髒讀 | 一個事物讀取了另外一個事物中未提交的數據。 |
---|---|
不可重複讀 | 一個事物內讀取表中某一行數據,屢次讀取結果不一樣。(更新操做) |
幻讀 | 一個事物內讀取到了別的事物插入的數據,致使先後不一致。(新增、刪除操做) |
髒讀 | 不可重複讀 | 幻讀 | |
---|---|---|---|
Read uncommitted | √ | √ | √ |
Read committed | × | √ | √ |
Repeatable read | × | × | √ |
Serializable | × | × | × |
Oracle:默認系統事務隔離級別是READ-COMMITTED。
Mysql:默認的事務處理級別是REPEATABLE-READ。
SQL Server:默認系統事務隔離級別是READ-COMMITTED。spring
Spring 事務管理
Spring中的事物是經過TransactionDefiniton 接口定義的
該接口包含了與事物相關的屬性和方法sql
public interface TransactionDefinition{
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = 1;
int ISOLATION_READ_COMMITTED = 2;
int ISOLATION_REPEATABLE_READ = 4;
int ISOLATION_SERIALIZABLE = 8;
int getIsolationLevel();
int getPropagationBehavior();
int getTimeout();
boolean isReadOnly();
}
複製代碼
TransactionDefinition接口中定義了五種表示隔離級別的常量數據庫
ISOLATION_DEFAULT(默認) | 底層數據庫的默認隔離級別。 對大部分數據庫而言, 常量值是 TransactionDefinition.ISOLATION_READ_COMMITTED |
---|---|
ISOLATION_READ_UNCOMMITTED | 該隔離級別表示一個事物能夠讀取另外一個事物中修改可是尚未提交的數據。 該隔離級別不能防止髒讀和不可重複讀。(不多使用) |
ISOLATION_READ_COMMITTED | 該隔離表示一個事物能夠讀取另外一個事物中已經提交的數據。 該隔離級別能夠防止髒讀。(推薦) |
ISOLATION_REPEATABLE_READ | 全部事物一次逐個執行,這樣事物之間就徹底不可能產生干擾。 該隔離級別能夠防止髒讀、不可重複讀和幻讀。(不推薦,影響性能) |
事物管理主要分爲兩大類:
(一)、編程式事物管理。
基於 TransactionDefinition、PlatformTransactionManager、TransactionStatus 編程式事務管理是 Spring 提供的最原始的方式。
基於 TransactionTemplate 的編程式事務管理是對上一種方式的封裝,使得編碼更簡單、清晰。
例:Hibernate中,咱們須要在代碼中顯式調用beginTransaction()、commit()、rollback()等事務管理相關的方法。
(二)、聲明式事物管理。
基於 TransactionInterceptor 的聲明式事務是 Spring 聲明式事務的基礎。
基於 TransactionProxyFactoryBean 的聲明式事務。( Spring 2.0 中已不推薦)
基於 和 命名空間的聲明式事務管理(推薦),與 Spring AOP 結合緊密,使得管理事務更加靈活。
例:express
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="bulk*" propagation="REQUIRED" isolation="DEFAULT" />
<tx:method name="load*" propagation="REQUIRED" isolation="DEFAULT" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor pointcut="execution(**.services(..))" advice-ref="txAdvice" />
</aop:config>
或
<aop:config>
<aop:pointcut id="allServiceMethods"
expression="execution(**.services(..))"/>
<aop:advisor advice-ref="defaultTransactionAdvice"
pointcut-ref="allServiceMethods"/>
</aop:config>
<tx:advice id="defaultTransactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method
name="*"
isolation="DEFAULT"
propagation="REQUIRED"
rollback-for="java.lang.RuntimeException"
timeout="100"/>
<tx:method
name="get*"
read-only="true"/>
</tx:attributes>
</tx:advice>
複製代碼
基於 @Transactional 的方式將聲明式事務管理
注:
做用於接口、接口方法、類、類中的方法。不推薦在接口中使用該註解,由於只有基於接口的代理時纔會生效。
只能夠用在public方法上,在protected、private使用時,會被忽略。 沒法重用,只能做用於單個類或方法上,需逐個制定。編程
如我的理解有誤差:還請指正。
參考:https://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/
bash