@Transactional传播属性

时间:2025-02-15 07:01:43

required有则有无则创建(默认)

说明: 如果当前已经存在事务,那么加入该事务,如果不存在事务,创建一个事务,这是默认的传播属性值。

@Service
public class RequireMethodService {

	@Autowired
	UserService userService;

	@Transactional(propagation = )
	public void methodSon1() {
		User user = new User();
		(1);
		("A");
		(user);
		String act = ();
		("Transaction1-----" + act);
	}

	@Transactional(propagation = )
	public void methodSon2() {
		User user = new User();
		(2);
		("B");
		(user);
		String act = ();
		("Transaction2-----" + act);
	}

}
@Service
public class RequireService {

	@Autowired
	RequireMethodService requireMethodService;
	
	@Transactional
    public void service() {
		String act = ();
		("begin-----" + act);
		requireMethodService.methodSon1();
		requireMethodService.methodSon2();
    } 
    
}

执行结果:事务是相同的



supports有则有无则无事务

如果当前已经存在事务,那么加入该事务,否则创建一个所谓的空事务(可以认为无事务执行)。

@Service
public class SupportMethodService {

	@Autowired
	UserService userService;

	/**
	 * 如果当前有事务则加入事务中,如果没有则什么都不做,相当于没事务。
	 */
	@Transactional(propagation = )
	public void methodSon1() {
		User user = new User();
		(1);
		("A");
		(user);
		throw new RuntimeException("异常");
	}


}
@Service
public class SupportService {

	@Autowired
	SupportMethodService supportMethodService;
	
	/**
	 * @Transactional,开启事务后,service会和methodSon1公用一个事务,此时methodSon1会正常回滚;
	 * 
	 * 如果这里没有开启,则methodSon1不会自己创建事务。此时methodSon1会不会回滚,数据插入到数据库;
	 * 
	 */
	@Transactional
    public void service() {
		supportMethodService.methodSon1();
		
    } 
    
}

执行结果:
SupportService在调用SupportMethodService的过程中
1. SupportService没有事务,则methodSon1也没有事务,不会回滚,数据插入到数据库。
2. SupportService有事务,则methodSon1加入到事务中,会回滚。

mandatory必须有事务

当前必须存在一个事务,否则抛出异常。

@Service
public class MandatoryMethodService {

	@Autowired
	UserService userService;

	@Transactional(propagation = )
	public void methodSon1() {
		User user = new User();
		(1);
		("A");
		(user);
	}

	@Transactional(propagation = )
	public void methodSon2() {
		User user = new User();
		(2);
		("B");
		(user);
	}
	

}
@Service
public class MandatoryService {

	@Autowired
	MandatoryMethodService mandatoryMethodService;
	
	/**
	 * 当前必须存在一个事务,否则抛出异常。
	 * 
	 */
//	@Transactional
    public void service() {
		//没有事务
		mandatoryMethodService.methodSon1();
    } 
    
}

执行结果:

: No existing transaction found for transaction marked with propagation 'mandatory'
	at (:362) ~[spring-tx-5.3.:5.3.6]
	at (:595) ~[spring-tx-5.3.:5.3.6]
	at (:382) ~[spring-tx-5.3.:5.3.6]
	at (:119) ~[spring-tx-5.3.:5.3.6]
	at (:186) ~[spring-aop-5.3.:5.3.6]
	at $(:750) ~[spring-aop-5.3.:5.3.6]
	at $(:692) ~[spring-aop-5.3.:5.3.6]

never 必须没有事务

如果当前存在事务,则抛出异常

@Service
public class NeverMethodService {

	@Autowired
	UserService userService;

	@Transactional(propagation = )
	public void methodSon1() {
		User user = new User();
		(1);
		("A");
		(user);
	}

	@Transactional(propagation = )
	public void methodSon2() {
		User user = new User();
		(2);
		("B");
		(user);
	}
	

}
@Service
public class NeverService {

	@Autowired
	NeverMethodService neverMethodService;
	
	/**
	 * 如果当前存在事务,则抛出异常,否则在无事务环境上执行代码。
	 * 
	 * 如果调用方法上已经有事务,被调用方法上会报错。
	 */
	@Transactional
    public void service() {
		//methodSon1创建了事务,但不会影响methodSon2
    	neverMethodService.methodSon1();
    	//methodSon2此时会报错,因为service()上已经开启了事务
    	neverMethodService.methodSon2();
    } 
    
}

执行结果:

: Existing transaction found for transaction marked with propagation 'never'
	at (:413) ~[spring-tx-5.3.:5.3.6]
	at (:352) ~[spring-tx-5.3.:5.3.6]
	at (:595) ~[spring-tx-5.3.:5.3.6]
	at (:382) ~[spring-tx-5.3.:5.3.6]
	at (:119) ~[spring-tx-5.3.:5.3.6]
	at (:186) ~[spring-aop-5.3.:5.3.6]
	at $(:750) ~[spring-aop-5.3.:5.3.6]
	at $(:692) ~[spring-aop-5.3.:5.3.6]

requires_new新事务

REQUIRES_NEW新建一个事务,不管当前有没有事务,都新建一个独立的事务。

@Service
public class RequireNewMethodService {

	@Autowired
	UserService userService;

	@Transactional(propagation = )
	public void methodSon1() {
		User user = new User();
		(1);
		("A");
		(user);
		String act = ();
		("Transaction1-----" + act);
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void methodSon2() {
		User user = new User();
		(2);
		("B");
		(user);
		String act = ();
		("Transaction2-----" + act);
	}


}
@Service
public class RequireNewService {

	@Autowired
	RequireNewMethodService requireNewMethodService;
	
	/**
	 * REQUIRES_NEW新建一个事务,不管当前有没有事务,都新建一个独立的事务。
	 */
	@Transactional
    public void service() {
		String act = ();
		("begin-----" + act);
		requireNewMethodService.methodSon1();
		
		requireNewMethodService.methodSon2();
    } 
    
}

执行结果:

.
.
.RequireNewMethodService.methodSon2

nested嵌套事务

1)methodSon2方法内部报错,则只会回滚methodSon2里面的。

2)methodSon2方法内部不报错,但是外面的调用方报错了,则methodSon2会跟着一起回滚。

3)methodSon2方法内部不报错,外面也不报错,则methodSon2和外面事务一起提交。

@Service
public class NestedMethodService {

	@Autowired
	UserService userService;

	@Transactional(propagation = )
	public void methodSon1() {
		User user = new User();
		(1);
		("A");
		(user);
	}

	@Transactional(propagation = )
	public void methodSon2() {
		User user = new User();
		(2);
		("B");
		(user);
		throw new RuntimeException("methodSon2异常");
	}


}

@Service
public class NestedService {

	@Autowired
	NestedMethodService nestedMethodService;
	
	/**
	 * methodSon2方法内部报错,则只会回滚methodSon2里面的。
	 */
	@Transactional
    public void service() {
		nestedMethodService.methodSon1();
		try {
			nestedMethodService.methodSon2();
        } catch (Exception e) {
            ();
        }
    } 
	
	/**
	 * methodSon1方法内部不报错,但是外面的methodSon2报错了,则methodSon1会跟着一起回滚。
	 */
	@Transactional
    public void service2() {
		try {
			nestedMethodService.methodSon1();
        } catch (Exception e) {
            ();
        }
		nestedMethodService.methodSon2();
    } 
	
	
    
}

总结:

在methodA()调用methodB()情况下

REQUIRED REQUIRES_NEW NESTED
如果methodB()抛出异常,在methodA()中没有try catch住 A、B都回滚 A、B都回滚 A、B都回滚
如果methodB() 抛出异常,在methodA()中try catch住,没有重新抛出 A、B都回滚 A不回滚 B回滚 A不回滚 B回滚
如果methodB() 抛出异常,在methodA()中try catch住,重新抛出 A、B都回滚 A、B都回滚 A、B都回滚
如果只有methodA抛出异常(先执行B,后执行A) A、B都回滚 A回滚 B不回滚 A、B都回滚