spring自己沒有事務,spring事務是在數據庫事務的基礎上進行封裝拓展,spring支持聲明式事務、編程式事務兩種,本文主要針對聲明式事務進行講解,本篇文章爲《圖靈學院》課程筆記java
咱們在使用事務的時候無非是如下幾步git
其實spring是在框架中給我咱們作了開啓、提交/回滾的操做,使得業務代碼和事務操做解耦。那麼spring是如何實如今指定方法先後自動加上事務操做的呢;這就要扯到動態代理了spring
解決的問題:將次要業務、主要業務解耦。,次要業務:起到輔助做用,輔助主要業務順利實現,在項目中每每大量存在數據庫
具體例子以下:編程
接口markdown
public interface UserDao {
void save();
}
複製代碼
接口實現、目標對象併發
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("數據已經保存");
}
}
複製代碼
代理對象框架
public class ProxyFactory {
private Object target;
public ProxyFactory(Object object) {
this.target = object;
}
public Object getProxyObject(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),new InvocationHandler(){
/** * @param proxy 負責監聽的對象 * @param method 被攔截的業務方法 * @param args 被攔截業務方法的實參 * @return * @throws Throwable */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before do something...");
Object returnValue= method.invoke(target,args);
System.out.println("after do something...");
return returnValue;
}
});
}
}
複製代碼
測試方法ide
public static void main(String[] args) {
//目標對象
UserDao target = new UserDaoImpl();
//目標對象建立代理對像
UserDao proxy = (UserDao) new ProxyFactory(target).getProxyObject();
proxy.save();
}
複製代碼
輸出結果oop
結合着代理模式,spring事務的實現原理就容易理解了,業務邏輯就是主要業務,須要重複使用的事務就是次要業務,spring的事務就是經過動態代理在業務代碼的先後增長開啓、提交/回滾的操做,實現事務操做
spring事務特性以下
屬性 | 屬性值 | 描述 |
---|---|---|
支持當前事物 | PROPAGATION_REQUIRED(必須的) | 若是當前沒有事物,就新建一個事物,若是已經存在一個事物中,加入到這個事物中。這是最多見的選擇。 |
PROPAGATION_SUPPORTS(支持) | 支持當前事物,若是當前沒有事物,就以非事物方式執行。 | |
PROPAGATION_MANDATORY(強制) | 使用當前的事物,若是當前沒有事物,就拋出異常。 | |
不支持當前事物 | PROPAGATION_REQUIRES_NEW(隔離) | 新建事物,若是當前存在事物,把當前事物掛起。 |
PROPAGATION_NOT_SUPPORTED(不支持) | 以非事物方式執行操做,若是當前存在事物,就把當前事物掛起。 | |
PROPAGATION_NEVER(強制非事物) | 以非事物方式執行,若是當前存在事物,則拋出異常。 | |
套事物 | PROPAGATION_NESTED(嵌套事物) | 若是當前存在事物,則在嵌套事物內執行。若是當前沒有事物,則執行與PROPAGATION_REQUIRED相似的操做。 |
隔離級別 | 髒讀(Dirty Read) | 不可重複讀(NonRepeatable Read) | 幻讀(Phantom Read) |
---|---|---|---|
未提交讀(Read uncommitted) | 可能 | 可能 | 可能 |
已提交讀(Read committed) | 不可能 | 可能 | 可能 |
可重複讀(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(SERIALIZABLE) | 不可能 | 不可能 | 不可能 |
髒讀 :
一個事物讀取到另外一事物未提交的更新數據
不可重複讀 :
在同一事物中,屢次讀取同一數據返回的結果有所不一樣, 換句話說, 後續讀取能夠讀到另外一事物已提交的更新數據. 相反, 「可重複讀」在同一事物中屢次讀取數據時, 可以保證所讀數據同樣, 也就是後續讀取不能讀到另外一事物已提交的更新數據。
幻讀 :
查詢表中一條數據若是不存在就插入一條,併發的時候卻發現,裏面竟然有兩條相同的數據。這就幻讀的問題。
spring提供三個接口提供使用事務:
TransactionDefinition 事務定義
PlatformTransactionManager 事務管理
TransactionStatus 事務運行時狀態
原文地址