事务传播级别
事务传播级别是管理事务行为的一个重要概念,特别是在嵌套事务的场景中。在Java中,Spring框架提供了多种事务传播级别,用来控制当一个事务方法被另一个事务方法调用时,事务的行为。
1. PROPAGATION_REQUIRED
这是默认的传播级别。如果当前已经有一个事务在运行,那么被调用的方法将加入到这个现有的事务中。如果当前没有事务,那么一个新的事务将被创建。
用例:
适用于绝大多数场景,通常是首选。
示例:
假设方法A和方法B都是带有PROPAGATION_REQUIRED
的事务方法,方法A调用方法B。如果A在执行时已经开启了一个事务,那么B将不会创建新的事务,而是加入A的事务。这样,如果B的方法执行失败并抛出异常,整个事务(包括A和B)都会回滚。
2. PROPAGATION_SUPPORTS
如果当前有一个事务在进行,方法将加入该事务;如果没有事务在进行,方法将以非事务方式执行。
用例:
适用于那些需要在事务中执行,但又不强制要求开启事务的方法。
示例:
如果方法A调用了使用PROPAGATION_SUPPORTS
的B方法,并且A的事务没有被启动,B将以非事务方式运行。此时,即使B失败,也不会影响A的方法。
3. PROPAGATION_MANDATORY
要求当前方法必须在一个事务中执行。如果当前没有事务,Spring将抛出异常。
用例:
适用于那些必须在事务上下文中执行的操作。
示例:
如果方法A调用了PROPAGATION_MANDATORY
的B方法,而A没有事务,则B将抛出异常。
4. PROPAGATION_REQUIRES_NEW
每次调用该方法时都会创建一个新的事务,如果已经有事务在进行,那么当前事务将被挂起,直到新事务完成。
用例:
适用于需要在现有事务之外执行独立事务的场景。
示例:
假设方法A在事务中运行,并调用了PROPAGATION_REQUIRES_NEW
的B方法。B将暂停A的事务,创建自己的事务,并在完成后恢复A的事务。如果B失败并回滚,这不会影响A的事务。
5. PROPAGATION_NOT_SUPPORTED
当前方法不应在事务中运行。如果有事务在进行,它将被挂起。
用例:
适用于那些明确不应该在事务上下文中运行的操作,如只读查询。
示例:
如果方法A调用了PROPAGATION_NOT_SUPPORTED
的B方法,而A有一个事务正在进行,B将在非事务模式下运行,而A的事务将被挂起。
6. PROPAGATION_NEVER
与PROPAGATION_MANDATORY
相反,该级别表示当前方法不应该在事务中运行。如果有事务正在进行,Spring将抛出异常。
用例:
适用于绝对不希望在事务上下文中执行的方法。
示例:
如果方法A调用了PROPAGATION_NEVER
的B方法,而A有一个事务正在进行,B将抛出异常。
7. PROPAGATION_NESTED
当前方法在一个嵌套的事务中运行。如果当前事务回滚,则嵌套事务也将回滚,但嵌套事务的回滚不会影响外层事务。
用例:
适用于需要部分回滚的场景。
示例:
假设方法A调用了PROPAGATION_NESTED
的B方法。如果B发生了异常并回滚,只会回滚B的事务,不影响A的事务。
总结
PROPAGATION_REQUIRED
是最常用的,因为它可以确保方法在事务中运行,适合绝大多数场景。PROPAGATION_REQUIRES_NEW
是在需要完全独立事务时使用的,比如需要在事务失败后依然提交某些操作。PROPAGATION_NESTED
则在需要部分回滚的复杂场景下使用。