Spring事務管理 @Transactional

在service類前加上@Transactional,聲明這個service所有方法需要事務管理。每一個業務方法開始時都會打開一個事務。

Spring默認情況下會對運行期例外(RunTimeException)進行事務回滾。這個例外是unchecked

如果遇到checked意外就不回滾。

如何改變默認規則:

1 讓checked例外也回滾:在整個方法前加上 @Transactional(rollbackFor=Exception.class)

2 讓unchecked例外不回滾: @Transactional(notRollbackFor=RunTimeException.class)

3 不需要事務管理的(只查詢的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)

注意: 如果異常被try{}catch{}了,事務就不回滾了,如果想讓事務回滾必須再往外拋try{}catch{throw Exception}。

@Transactional(noRollbackFor=RuntimeException.class)方法事務說明
@Transactional(RollbackFor=Exception.class)
@Transactional(readOnly=true)
@Transactional(timeout=100)
@Transactional(isolation)數據庫的隔離級別
{
Read Uncommited:讀取未提交的數據(會出現髒讀不可重複讀 幻讀)
Read Commited:讀已提交的數據(會出現不可重複讀和幻讀)
Repeatable Read:可重複讀(會出現幻讀)
Serializable:串行化
}

髒讀:一個事務讀取到另外一個事務未提交的更新的數據
不可重複讀:在同一事務中,多次讀取同一個數據返回結果有所不同,就是後續的讀取可以讀到另外一個事務的已經的已經提交的更新數據
可重複讀:在同一個事務多次讀取數據時,能夠保證所讀取的數據一樣,也就是後讀取的不能讀到另外一個事務已經提交的數據
幻讀:一個事務讀取到另外一個事務已經提交的更新的數據

針對查詢方法
@Transactional(propagation=Propagation.NOT_SUPPORTED)針對某個方法不開啓事務
@Transactional(propagation=Propagation.REQUIRED)默認的事務支持

例子:
public class Bean1 {
@Transactional(propagation=Propagation.Required)
public void update() {
executeUpdate(SQL);
}
}
public class Bean2 {
@Transactional(propagation=Propagation.SUPPORTS)
public void update() {
executeUpdate(SQL);
}
}

public class Transaction {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void test1()
{
bean1.update();
bean2.update();
}
@Transactional(propagation=Propagation.NOT_SUPPORTED)
public void test2()
{
bean1.update();
bean2.update();
}
@Transactional(propagation=Propagation.SUPPORTS)
public void test3()
{
bean1.update();
bean2.update();
}
}

//事務傳播屬性
@Transactional(propagation=Propagation.REQUIRED)//如果有事務,那麼加入事務,沒有的話新創建一個
@Transactional(propagation=Propagation.NOT_SUPPORTED)//這個方法不開啓事務
@Transactional(propagation=Propagation.REQUIREDS_NEW)//不管是否存在事務,都創建一個新的事務,原來的掛起,新的執行完畢,繼續執行老的事務
@Transactional(propagation=Propagation.MANDATORY)//必須在一個已有的事務中執行,否則拋出異常
@Transactional(propagation=Propagation.NEVER)//不能在一個事務中執行,就是當前必須沒有事務,否則拋出異常
@Transactional(propagation=Propagation.SUPPORTS)//其他bean調用這個方法,如果在其他bean中聲明瞭事務,就是用事務。沒有聲明,就不用事務。
@Transactional(propagation=Propagation.NESTED)//如果一個活動的事務存在,則運行在一個嵌套的事務中,如果沒有活動的事務,則按照REQUIRED屬性執行,它使用一個單獨的事務。這個書屋擁有多個回滾的保存點,內部事務的回滾不會對外部事務造成影響,它只對DataSource TransactionManager事務管理器起效。
@Transactional(propagation=Propagation.REQUIRED,readOnly=true)//只讀,不能更新,刪除
@Transactional(propagation=Propagation.REQUIRED,timeout=30)//超時30秒
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)//數據庫隔離級別



參考資料有:
http://www.cnblogs.com/xupei/archive/2011/01/07/1929632.html
http://hi.baidu.com/qmzwhl/blog/item/aae2d6581afd17d29d8204ca.html

spring 事務註解

默認遇到throw new RuntimeException("...");會回滾
需要捕獲的throw new Exception("...");不會回滾

// 指定回滾
@Transactional(rollbackFor=Exception.class)
public void methodName() {
// 不會回滾
throw new Exception("...");
}
//指定不回滾
@Transactional(noRollbackFor=Exception.class)
public ItimDaoImpl getItemDaoImpl() {
// 會回滾
throw new RuntimeException("註釋");
}

// 如果有事務,那麼加入事務,沒有的話新建一個(不寫的情況下)
@Transactional(propagation=Propagation.REQUIRED)
// 容器不爲這個方法開啓事務
@Transactional(propagation=Propagation.NOT_SUPPORTED)
// 不管是否存在事務,都創建一個新的事務,原來的掛起,新的執行完畢,繼續執行老的事務
@Transactional(propagation=Propagation.REQUIRES_NEW)
// 必須在一個已有的事務中執行,否則拋出異常
@Transactional(propagation=Propagation.MANDATORY)
// 必須在一個沒有的事務中執行,否則拋出異常(與Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.NEVER)
// 如果其他bean調用這個方法,在其他bean中聲明事務,那就用事務.如果其他bean沒有聲明事務,那就不用事務.
@Transactional(propagation=Propagation.SUPPORTS)

/*
public void methodName(){
// 本類的修改方法 1
update();
// 調用其他類的修改方法
otherBean.update();
// 本類的修改方法 2
update();
}
other失敗了不會影響 本類的修改提交成功
本類update的失敗,other也失敗
*/
@Transactional(propagation=Propagation.NESTED)
// readOnly=true只讀,不能更新,刪除
@Transactional (propagation = Propagation.REQUIRED,readOnly=true)
// 設置超時時間
@Transactional (propagation = Propagation.REQUIRED,timeout=30)
// 設置數據庫隔離級別
@Transactional (propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章