spring的事务怎么传递的

worktile 其他 84

回复

共3条回复 我来回复
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    Spring的事务传递是通过TransactionPropagation(事务传播)来实现的。在Spring中,事务可以嵌套传递给其他方法或者类,确保多个方法或者类在同一个事务中执行。

    Spring定义了7种事务传播行为,分别是:

    1. REQUIRED(默认):如果当前存在事务,则加入该事务;如果没有事务,则创建一个新事务。

    2. SUPPORTS:支持事务,如果当前存在事务,则加入该事务;如果没有事务,则以非事务方式执行。

    3. MANDATORY:强制要求使用事务,如果当前存在事务,则加入该事务;如果没有事务,则抛出异常。

    4. REQUIRES_NEW:创建一个新事务,如果当前存在事务,则挂起该事务。

    5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则挂起该事务。

    6. NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。

    7. NESTED:如果当前存在事务,则在嵌套事务中执行;如果没有事务,则执行与REQUIRED相同的操作。

    事务传递的方式可以通过在方法上使用@Transactional注解来指定,同时可以通过在配置文件中进行配置。使用@Transactional注解在方法上,可以单独配置每个方法的事务传播行为,配置文件中的配置则可以对整个应用程序进行全局配置。

    总结来说,Spring的事务传递是通过定义不同的事务传播行为来实现的。根据具体的需求,可以选择合适的传播行为来控制事务的传递方式。

    1年前 0条评论
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    在Spring中,事务的传递是通过TransactionTemplate或注解的方式实现的。下面是关于Spring事务传递的5个重要点:

    1. 默认的事务传播行为:
      Spring的事务传播行为默认为REQUIRED,即如果当前方法已经存在事务,则加入该事务中,否则创建一个新的事务。这意味着,如果一个方法A调用另一个方法B,而方法A已经开启了一个事务,那么方法B将会在方法A的事务中执行。如果方法B抛出异常,事务将会回滚;如果方法A抛出异常,方法B也将回滚。

    2. 支持的事务传播行为:
      Spring支持下面7种事务传播行为:

    • REQUIRED: 如果当前方法已经存在事务,则加入该事务中;否则创建一个新的事务。
    • SUPPORTS: 如果当前方法已经存在事务,则加入该事务中;否则以非事务的方式执行。
    • MANDATORY: 必须在一个已经存在的事务中执行。如果当前方法没有事务,则抛出异常。
    • REQUIRES_NEW: 创建一个新的事务,并挂起当前事务(如果存在)。
    • NOT_SUPPORTED: 以非事务的方式执行,并挂起当前事务(如果存在)。
    • NEVER: 以非事务的方式执行,如果当前存在事务,则抛出异常。
    • NESTED: 如果当前方法已经存在事务,则在当前事务的嵌套事务中执行;否则创建一个新的事务。
    1. 事务的传播行为控制:
      可以通过在方法上使用@Transactional注解来指定事务的传播行为。例如:
    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() {
        // 代码逻辑
    }
    
    1. 相同的事务上下文:
      在一个事务中,多个方法之间可以共享相同的事务上下文。这意味着,如果方法A调用方法B,而两个方法都在同一个事务中执行,它们将共享同一个连接、同一个事务管理器等。

    2. 事务的回滚:
      在Spring中,如果方法抛出了一个未被捕获的RuntimeException或Error,事务将会回滚。如果方法抛出了一个被Checked Exception修饰的异常,则不会回滚事务,可以通过@Transactional注解的rollbackFor属性来指定希望回滚的异常类型。

    上述是关于Spring事务传递的5个重要点,对于了解和使用Spring事务非常有帮助。

    1年前 0条评论
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    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年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部