深入Spring資料庫事務管理

2021-08-13 14:46:12 字數 2998 閱讀 5607

相關問題

一、@transactional的失效問題

1.對於靜態(static)方法和非public方法,註解@transactional是失效的。

2.自呼叫,就是乙個類的乙個方法去呼叫自身另外乙個方法的過程。如下:

@autowired

private roledao roledao;

@transactional(propagation = propagation.requires_new, isolation = isolation.read_committed)

public int insertrole(role role)

@override

@transactional(propagation = propagation.required, isolation = isolation.read_committed)

public int insertrolelist(listrolelist) catch (exception ex)

}return count;

}

分析:角色插入兩次都使用的是同一事務,也就是說在insertrole方法上標註的@transactional失效了。原因在於aop的實現原理,這裡不再贅述。

@service

public class roleserviceimpl implements roleservice

}

②從ioc容器中獲取roleservice**物件。【不推薦,從容器獲取**物件有侵入之嫌,我們需要依賴於springioc容器】
@override

@transactional(propagation = propagation.required, isolation = isolation.read_committed)

public int insertrolelist(listrolelist) catch (exception ex)

}return count;

}

二、典型錯誤用法

1.錯誤使用service

場景:在乙個controller中插入兩個角色,並且兩個角色需要在同乙個事務中處理。

錯誤**:

public class rolecontroller 

}

分析:如果這個service標註用@transactional,那麼它就會啟用乙個事務,而乙個service方法完成後,它就會釋放該事務,所以前後兩個insertrole是在兩個不同的事務中完成的。這樣如果第乙個插入成功了,第二個插入失敗了,就會使資料庫資料庫資料不完全同時成功或者失敗,可能產生嚴重的資料不一致的問題。

2.過長時間占用事務

**:

@override

@transactional(propagation = propagation.requires_new, isolation = isolation.read_committed)

public int insertrole(role role)

分析:當insertrole方法結束後spring才會釋放資料庫事務資源,也就是說要等到dosomethingforfile()方法執行完成後,返回result後才會關閉資料庫資源。高併發情況下就會出現卡頓狀態,甚至因得不到資料庫資源而導致系統宕機。

解決:這個方法放在controller中執行

@responsebody

public role addrole(role role)

3.錯誤捕捉異常

場景:購買商品。其中productservice是產品服務類,而transactionservice是記錄交易資訊,需求就是產品減庫存和儲存交易在同乙個事務例,要麼同時成功,要麼同時失敗。假設傳播行為都是required。

**:

@autowired

private productservice productservice;

@autowired

private transactionservice transactionservice;

@override

@transactional(propagation = propagation.required, isolation = isolation.read_committed)

public int dotransaction(transactionbean trans)

}catch (exception ex)

return result;

}

分析:這裡的問題是方法已經存在異常了,由於開發者不了解spring的事務約定,在兩個操作方法裡面加入了自己的try.catch...語句,就可能發生這樣的結果:當減少庫存成功了,但是儲存交易資訊時失敗而發生了異常。由於加入的try.catch...語句,spring在資料庫事務所約定的流程中再也得不到任何異常資訊了,此時spring就會提交事務,啊這樣就出現了庫存減少,而交易記錄卻沒有的糟糕情況。

解決:在catch中自行丟擲異常,這樣在spring的事務流程彙總,就會捕捉到這個異常,進行事務回滾。

@autowired

private productservice productservice;

@autowired

private transactionservice transactionservice;

@override

@transactional(propagation = propagation.required, isolation = isolation.read_committed)

public int dotransaction(transactionbean trans)

}catch (exception ex)

return result;

}

Spring資料庫事務管理

事務 transaction 是併發控制的基本單位。所謂的事務,它是乙個操作序列,這些操作要麼都執行,要麼都不執行,它是乙個不可分割的工作單位。例如,銀行轉賬工作 從乙個賬號扣款並使另乙個賬號增款,這兩個操作要麼都執行,要麼都不執行,在關聯式資料庫中,乙個事務可以是一條sql語句 一組sql語句或整...

資料庫事務管理

一 事務的特性 acid 二 3個問題 幻讀和不可重複讀看起來一樣,但鎖的機制不同,幻讀對應insert和delete 操作,不可重複讀對應update操作 具體說就是不可重複讀鎖定一行資料,是行鎖,幻讀鎖定整個條件區域,是序列鎖。三 樂觀鎖和悲觀所 以上說的鎖,通過資料庫的鎖機制控制,鎖定後其他操...

spring 事務管理與資料庫隔離級別

1遇到問題 spring 事務中儲存了物件後 啟動乙個執行緒獲取物件無效 public void postdispatchdoc dispatchdoc entity catch exception e public void run catch exception e 寫web專案的時候,我們一般...