Spring的事務的傳播屬性

Spring事務有7種傳播屬性:
1.PROPAGATION_REQUIRED:如果存在一個事務,則支持當前事務。如果沒有事務則開啓一個新的事務。
2.PROPAGATION_SUPPORTS:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
3.PROPAGATION_MANDATORY:支持當前事務,如果當前沒有事務,就拋出異常。
4.PROPAGATION_REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。
5.PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
6.PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。
7.PROPAGATION_NESTED:支持當前事務,新增Savepoint點,與當前事務同步提交或回滾。 嵌套事務一個非常重要的概念就是內層事務依賴於外層事務。外層事務失敗時,會回滾內層事務所做的動作。而內層事務操作失敗並不會引起外層事務的回滾。

下面,我們以PROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEW來寫一個示例:

    @Transactional
	@Override
	public void addUser() {
		User user1 = new User();
		user1.setUserName("zhaoliu21");
		user1.setName("趙柳21");
		user1.setPassword("12323");
		user1.setSex(1);
		user1.setUserType(12);
		user1.setStatus(1);
		user1.setOrganizationId(12);
		userMapper.insert(user1);
		try {
			((UserService)AopContext.currentProxy()).updateUser(user1);
		}catch (Exception e) {
			System.out.println("ArithmeticException****************************");
			e.printStackTrace();
		}		
	}

    @Transactional(propagation=Propagation.REQUIRES_NEW)
	@Override
	public void updateUser(User user) {
		System.out.println("************updateUser  開始**************");
		User user1 = new User();
		user1.setId(46L);
		user1.setName("王武");
		userMapper.updateUserById(user1);
		System.out.println("************updateUser  結束**************");
		int a = 1/0;		
	}

當調用updateUser()時,會重新開啓一個事務,由於程序執行1/0會報異常,要保證內部事務回滾,外部事務正常提交,那麼就要在addUser()中調用updateUser()時進行try{}catch () {}處理。

    @Transactional
	@Override
	public void addUser() {
		User user1 = new User();
		user1.setUserName("zhaoliu21");
		user1.setName("趙柳21");
		user1.setPassword("12323");
		user1.setSex(1);
		user1.setUserType(12);
		user1.setStatus(1);
		user1.setOrganizationId(12);
		userMapper.insert(user1);
		((UserService)AopContext.currentProxy()).updateUser(user1);		
		int a = 1/0;
	}

    @Transactional(propagation=Propagation.REQUIRES_NEW)
	@Override
	public void updateUser(User user) {		
		System.out.println("************updateUser  開始**************");
		User user1 = new User();
		user1.setId(46L);
		user1.setName("王武");
		userMapper.updateUserById(user1);
		System.out.println("************updateUser  結束**************");
	}

如上代碼,當addUser()程序異常時,外部事務回滾,內部事務會正常提交。


void methodA(){
	service.methodB();
}

void methodB(){

}

這裏有A,B兩個方法,在A方法中調用B方法。分如下兩種情況:
一、運行的B方法出現異常
1.不做處理
新建事務:影響外部事務,影響自己
嵌套事務:影響外部事務,影響自己
共享事務:影響外部事務,影響自己

2.B方法拋出異常,由A方法內部處理
新建事務:不影響外部事務,影響自己
嵌套事務:不影響外部事務,影響自己
共享事務:影響外部事務,影響自己

3.B方法內部處理
不影響任何事務

4.兩個方法都拋異常
等同不做處理

二、運行的A方法出現異常,B方法不出現異常
1.不做處理
新建事務:影響自己,不影響內部事務
嵌套事務:影響自己,影響內部事務
共享事務:影響自己,影響內部事務

2.A方法內部處理
新建事務:全部不影響
嵌套事務:全部不影響
共享事務:全部不影響

3.A方法拋異常
等同不做處理


騰訊雲618大促騰訊雲618鉅惠
阿里雲最高2000代金券阿里雲新購、續費、升級優惠券

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