spring的事务怎么传递的
-
Spring的事务传递是通过TransactionPropagation(事务传播)来实现的。在Spring中,事务可以嵌套传递给其他方法或者类,确保多个方法或者类在同一个事务中执行。
Spring定义了7种事务传播行为,分别是:
-
REQUIRED(默认):如果当前存在事务,则加入该事务;如果没有事务,则创建一个新事务。
-
SUPPORTS:支持事务,如果当前存在事务,则加入该事务;如果没有事务,则以非事务方式执行。
-
MANDATORY:强制要求使用事务,如果当前存在事务,则加入该事务;如果没有事务,则抛出异常。
-
REQUIRES_NEW:创建一个新事务,如果当前存在事务,则挂起该事务。
-
NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则挂起该事务。
-
NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。
-
NESTED:如果当前存在事务,则在嵌套事务中执行;如果没有事务,则执行与REQUIRED相同的操作。
事务传递的方式可以通过在方法上使用@Transactional注解来指定,同时可以通过在配置文件中进行配置。使用@Transactional注解在方法上,可以单独配置每个方法的事务传播行为,配置文件中的配置则可以对整个应用程序进行全局配置。
总结来说,Spring的事务传递是通过定义不同的事务传播行为来实现的。根据具体的需求,可以选择合适的传播行为来控制事务的传递方式。
1年前 -
-
在Spring中,事务的传递是通过TransactionTemplate或注解的方式实现的。下面是关于Spring事务传递的5个重要点:
-
默认的事务传播行为:
Spring的事务传播行为默认为REQUIRED,即如果当前方法已经存在事务,则加入该事务中,否则创建一个新的事务。这意味着,如果一个方法A调用另一个方法B,而方法A已经开启了一个事务,那么方法B将会在方法A的事务中执行。如果方法B抛出异常,事务将会回滚;如果方法A抛出异常,方法B也将回滚。 -
支持的事务传播行为:
Spring支持下面7种事务传播行为:
- REQUIRED: 如果当前方法已经存在事务,则加入该事务中;否则创建一个新的事务。
- SUPPORTS: 如果当前方法已经存在事务,则加入该事务中;否则以非事务的方式执行。
- MANDATORY: 必须在一个已经存在的事务中执行。如果当前方法没有事务,则抛出异常。
- REQUIRES_NEW: 创建一个新的事务,并挂起当前事务(如果存在)。
- NOT_SUPPORTED: 以非事务的方式执行,并挂起当前事务(如果存在)。
- NEVER: 以非事务的方式执行,如果当前存在事务,则抛出异常。
- NESTED: 如果当前方法已经存在事务,则在当前事务的嵌套事务中执行;否则创建一个新的事务。
- 事务的传播行为控制:
可以通过在方法上使用@Transactional注解来指定事务的传播行为。例如:
@Transactional(propagation = Propagation.REQUIRED) public void methodA() { // 代码逻辑 }-
相同的事务上下文:
在一个事务中,多个方法之间可以共享相同的事务上下文。这意味着,如果方法A调用方法B,而两个方法都在同一个事务中执行,它们将共享同一个连接、同一个事务管理器等。 -
事务的回滚:
在Spring中,如果方法抛出了一个未被捕获的RuntimeException或Error,事务将会回滚。如果方法抛出了一个被Checked Exception修饰的异常,则不会回滚事务,可以通过@Transactional注解的rollbackFor属性来指定希望回滚的异常类型。
上述是关于Spring事务传递的5个重要点,对于了解和使用Spring事务非常有帮助。
1年前 -
-
Spring框架提供了一种简单且灵活的方式,可以在应用程序中管理事务。在Spring中,事务传递是通过
Propagation(传播行为)来控制的。在这篇文章中,我们将详细介绍Spring事务的传播机制,并讨论不同的传播行为以及它们是如何在嵌套调用中传递的。1. 什么是事务传播行为
事务传播行为是指在多个事务之间如何传递和共享事务状态的方式。在Spring中,一个事务可以由一个或多个方法来触发,并且可以有不同的传播行为来控制这些方法之间事务的传递。
Spring提供了七种事务传播行为,它们分别是:
-
REQUIRED:如果当前没有事务,就创建一个新的事务;如果已存在一个事务中,则加入到这个事务中。
-
SUPPORTS:如果当前有事务,就加入到这个事务中;如果当前没有事务,则以非事务状态执行。
-
MANDATORY:如果当前有事务,就加入到这个事务中;如果当前没有事务,则抛出异常。
-
REQUIRES_NEW:无论当前是否存在事务,都创建一个新的事务,并在它自己的事务中执行。
-
NOT_SUPPORTED:以非事务状态执行,并且如果当前存在事务,则将其挂起。
-
NEVER:以非事务状态执行,并且如果当前存在事务,则抛出异常。
-
NESTED:如果当前有事务,则在一个嵌套的事务中执行;如果当前没有事务,则创建一个新的事务。
2. 事务传播行为示例
为了更好地理解事务传播行为,让我们通过一个示例来演示不同传播行为之间事务的传递。
假设我们有两个Service层的方法,分别是
methodA()和methodB()。@Service public class ExampleService { @Autowired private UserDao userDao; @Transactional(propagation = Propagation.REQUIRED) public void methodA() { // 执行一些业务逻辑 methodB(); } @Transactional(propagation = Propagation.REQUIRED) public void methodB() { // 执行一些业务逻辑 } }在上面的示例中,我们使用
@Transactional注解来标记方法需要进行事务管理,并使用Propagation.REQUIRED来设置事务的传播行为为REQUIRED。在这个示例中,我们假设方法
methodA()是外部方法,而方法methodB()是内部方法,内部方法被外部方法调用。下面,我们将根据不同的传播行为来演示事务的传递行为:
REQUIRED传播行为
设置
Propagation.REQUIRED事务传播行为时,如果当前没有事务,则创建一个新的事务,并且methodA()和methodB()将在同一个事务中执行。如果
methodA()正常执行,而methodB()抛出异常,那么methodA()和methodB()中对数据库的操作都将回滚。@Transactional(propagation = Propagation.REQUIRED) public void methodA() { userDao.updateUser(); // 更新数据库操作 methodB(); // ... } @Transactional(propagation = Propagation.REQUIRED) public void methodB() { userDao.insertUser(); // 插入数据库操作 throw new RuntimeException("Some error occurred"); }SUPPORTS传播行为
设置
Propagation.SUPPORTS事务传播行为时,如果当前有事务,methodA()和methodB()将在同一个事务中执行;如果当前没有事务,则以非事务状态执行methodA()和methodB()。@Transactional(propagation = Propagation.SUPPORTS) public void methodA() { userDao.updateUser(); // 更新数据库操作 methodB(); // ... } @Transactional(propagation = Propagation.SUPPORTS) public void methodB() { userDao.insertUser(); // 插入数据库操作 }MANDATORY传播行为
设置
Propagation.MANDATORY事务传播行为时,如果当前有事务,methodA()和methodB()将在同一个事务中执行;如果当前没有事务,则抛出异常。@Transactional(propagation = Propagation.MANDATORY) public void methodA() { userDao.updateUser(); // 更新数据库操作 methodB(); // ... } @Transactional(propagation = Propagation.MANDATORY) public void methodB() { userDao.insertUser(); // 插入数据库操作 }REQUIRES_NEW传播行为
设置
Propagation.REQUIRES_NEW事务传播行为时,不论当前是否存在事务,都会创建一个新的事务,并在新的事务中执行methodA()和methodB()。@Transactional(propagation = Propagation.REQUIRES_NEW) public void methodA() { userDao.updateUser(); // 更新数据库操作 methodB(); // ... } @Transactional(propagation = Propagation.REQUIRES_NEW) public void methodB() { userDao.insertUser(); // 插入数据库操作 }NOT_SUPPORTED传播行为
设置
Propagation.NOT_SUPPORTED事务传播行为时,methodA()和methodB()都以非事务状态执行,并且如果当前存在事务,则将其挂起。@Transactional(propagation = Propagation.NOT_SUPPORTED) public void methodA() { userDao.updateUser(); // 更新数据库操作 methodB(); // ... } @Transactional(propagation = Propagation.NOT_SUPPORTED) public void methodB() { userDao.insertUser(); // 插入数据库操作 }NEVER传播行为
设置
Propagation.NEVER事务传播行为时,methodA()和methodB()都以非事务状态执行,并且如果当前存在事务,则抛出异常。@Transactional(propagation = Propagation.NEVER) public void methodA() { userDao.updateUser(); // 更新数据库操作 methodB(); // ... } @Transactional(propagation = Propagation.NEVER) public void methodB() { userDao.insertUser(); // 插入数据库操作 }NESTED传播行为
设置
Propagation.NESTED事务传播行为时,如果当前有事务,则在一个嵌套的事务中执行methodA()和methodB();如果当前没有事务,则创建一个新的事务。@Transactional(propagation = Propagation.NESTED) public void methodA() { userDao.updateUser(); // 更新数据库操作 methodB(); // ... } @Transactional(propagation = Propagation.NESTED) public void methodB() { userDao.insertUser(); // 插入数据库操作 }3. 事务传播行为的选择
在实际项目中,我们需要根据具体的业务需求来选择合适的事务传播行为。
通常来说,大多数业务场景下使用
Propagation.REQUIRED(默认值)是最常见的选择,因为它会根据情况自动创建一个新的事务以及合并现有事务。如果我们需要确保某个方法在拥有自己的事务环境中执行,并且不受调用者事务的影响,那么可以选择
Propagation.REQUIRES_NEW来创建一个新的事务。如果我们需要在一个事务中执行一组相关的操作,并且如果其中某个操作失败,可以回滚这组相关的操作,那么可以选择
Propagation.NESTED来创建一个嵌套事务。另外,需要注意的是,在进行事务传播行为的选择时,还应考虑到数据库的隔离级别、并发控制和性能等方面。
4. 总结
Spring框架通过事务传播行为提供了一种简单而强大的机制来管理事务。在实际项目中,我们可以根据具体的业务需求选择适当的传播行为。
本文介绍了Spring框架中的事务传播行为,包括每种传播行为的含义、示例及其在嵌套调用中的传递方式。
通过对事务传播行为的理解和选择,我们能够更好地管理和控制事务,并确保数据的一致性和完整性。
1年前 -