Spring事务的传播行为分析

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 最近项目有涉及到Spring事务,所以工作之余,想认真了解学习下Spring事务,查阅了若干资料,做了一个demo

前言


最近项目有涉及到Spring事务,所以工作之余,想认真了解学习下Spring事务,查阅了若干资料,做了一个demo(PS:参考了大牛的)。


现分享总结如下:


1、Spring 事务的简介

理解事务之前,


先讲一个你日常生活中最常干的事:取钱。

比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱;然后ATM出1000元钱。这两个步骤必须是要么都执行要么都不执行。如果银行卡扣除了1000块但是ATM出钱失败的话,你将会损失1000元;如果银行卡扣钱失败但是ATM却出了1000块,那么银行将损失1000元。所以,如果一个步骤成功另一个步骤失败对双方都不是好事,如果不管哪一个步骤失败了以后,整个取钱过程都能回滚,也就是完全取消所有操作的话,这对双方都是极好的。

事务就是用来解决类似问题的。事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。

在企业级应用程序开发中,事务管理必不可少的技术,用来确保数据的完整性和一致性。

事务有四个特性:ACID


原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。

一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。

隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。

持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

具体可以参考:http://www.mamicode.com/info-detail-1248286.html


2、事务的传播行为

事务的第一个方面是传播行为(propagation behavior)。当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。Spring定义了七种传播行为:


1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。


2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。‘


3、PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。


4、PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。


5、PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。


6、PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。


7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。


下面我们来看下代码:


3、demo分析

事先插入一条记录

@Override
    public void before() {
        jdbcTemplate.update("INSERT  INTO USER (name,password) VALUES (?,?)","xiang","11111112");
    }

 3.1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

@Override
    public void txRollbackInnerTxRollbackPropagationRequires() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                jdbcTemplate.update("INSERT INTO  USER (name,password) VALUES (?,?)","Huang","1111231");
                transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                        jdbcTemplate.update("insert into user name, password) values (?, ?)",
                                "Huang", "1111112");
                        //内部事务设置了 setRollbackOnly
                        transactionStatus.setRollbackOnly();
                    }
                });
            }
        });
    }


测试结果:

/**
     * PROPAGATION_REQUIRES:内部事务设置了 {@link org.springframework.transaction.TransactionStatus#setRollbackOnly()} 来触发回滚,
     * 外部事务接受到了一个 {@link UnexpectedRollbackException} 也被回滚
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationRequires() throws Exception {
        try {
            springTxService.txRollbackInnerTxRollbackPropagationRequires();
        } catch (UnexpectedRollbackException e) {
        }finally {
            Assert.assertEquals(1,springTxService.mysqlConnection());
        }
    }


3.2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

@Override
    public void txRollbackInnerTxRollbackPropagationSupports() {
        supportsTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
                        "1111112");
                throw new CustomRuntimeException();
            }
        });
    }
    @Override
    public void txRollbackInnerTxRollbackPropagationSupports2() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
                        "1111112");
                supportsTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus status) {
                        jdbcTemplate.update("insert into user (name, password) values (?, ?)",
                                "Huang", "1111112");
                        status.setRollbackOnly();
                    }
                });
            }
        });
    }


测试用例:

/**
     * PROPAGATION_SUPPORTS:如果当前事务上下文中没有事务,
     * 那么就按照没有事务的方式执行代码
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationSupports() throws Exception {
        try {
            springTxService.txRollbackInnerTxRollbackPropagationSupports();
        } catch (CustomRuntimeException e) {
            e.printStackTrace();
        }finally {
            Assert.assertEquals(2, springTxService.mysqlConnection());
        }
    }
    /**
     * PROPAGATION_SUPPORTS:如果当前事务上下文中存在事务,
     * 那么合并到当前上下文的事务中去,
     * 表现地和 {@link org.springframework.transaction.TransactionDefinition#PROPAGATION_REQUIRED} 一样
     */
    @Test(expected = UnexpectedRollbackException.class)
    public void testTxRollbackInnerTxRollbackPropagationSupports2() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationSupports2();
    }

3.3、PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

@Override
    public void txRollbackInnerTxRollbackPropagationMandatory() {
        mandatoryTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
                        "1111112");
            }
        });
    }
    @Override
    public void txRollbackInnerTxRollbackPropagationMandatory2() {
        nestedTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
                        "1111112");
                mandatoryTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                        jdbcTemplate.update("insert into user (name, password) values (?, ?)",
                                "Huang", "1111112");
                        //内部事务回滚了,外部事务也跟着回滚
                        transactionStatus.setRollbackOnly();
                    }
                });
            }
        });
    }

测试用例:

/**
     * PROPAGATION_MANDATORY:强制性的事务,当前的事务上下文中不存在事务的话,会抛出 {@link IllegalTransactionStateException}
     */
    @Test(expected = IllegalTransactionStateException.class)
    public void testTxRollbackInnerTxRollbackPropagationMandatory() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationMandatory();
    }
    /**
     * PROPAGATION_MANDATORY:强制性的事务,内部的事务发生回滚,
     * 那么外部的事务也会发生回滚,表现地和 {@link org.springframework.transaction.TransactionDefinition#PROPAGATION_REQUIRED}
     * 一样,也会抛出 {@link UnexpectedRollbackException}
     */
    @Test(expected = UnexpectedRollbackException.class)
    public void testTxRollbackInnerTxRollbackPropagationMandatory2() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationMandatory2();
    }


3.4、PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

@Override
    public void txRollbackInnerTxRollbackPropagationRequiresNew() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                requiresNewTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                        jdbcTemplate.update("insert into user (name, password) values (?, ?)",
                                "Huang", "1111112");
                    }
                });
                //外部事务发生回滚,内部事务应该不受影响还是能够提交
                throw new RuntimeException();
            }
        });
    }
    @Override
    public void txRollbackInnerTxRollbackPropagationRequiresNew2() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
                        "1111112");
                requiresNewTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                        jdbcTemplate.update("insert into user (name, password) values (?, ?)",
                                "Huang", "1111112");
                        // 内部事务发生回滚,但是外部事务不应该发生回滚
                        transactionStatus.setRollbackOnly();
                    }
                });
            }
        });
    }
    @Override
    public void txRollbackInnerTxRollbackPropagationRequiresNew3() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
                        "1111112");
                requiresNewTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                        jdbcTemplate.update("insert into user (name, password) values (?, ?)",
                                "Huang", "1111112");
                        // 内部事务抛出 RuntimeException,外部事务接收到异常,依旧会发生回滚
                        throw new RuntimeException();
                    }
                });
            }
        });
    }

测试用例:

/**
     * PROPAGATION_REQUIRES_NEW:外部事务发生回滚,内部事务继续提交,不受影响
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationRequiresNew() throws Exception {
        try {
            springTxService.txRollbackInnerTxRollbackPropagationRequiresNew();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            Assert.assertEquals(2,springTxService.mysqlConnection());
        }
    }
    /**
     * PROPAGATION_REQUIRES_NEW:内部事务通过设置 {@link org.springframework.transaction.TransactionStatus#setRollbackOnly()} 来触发回滚,
     * 外部事务依旧可以不受影响,正常提交
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationRequiresNew2() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationRequiresNew2();
        Assert.assertEquals(2,springTxService.mysqlConnection());
    }
    /**
     * PROPAGATION_REQUIRES_NEW:内部事务抛出了 {@link RuntimeException} 异常发生了回滚,外部事务接收到这个异常也会发生回滚
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationRequiresNew3() throws Exception {
        try {
            springTxService.txRollbackInnerTxRollbackPropagationRequiresNew3();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }finally {
            Assert.assertEquals(1,springTxService.mysqlConnection());
        }
    }


3.5、PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

@Override
    public void txRollbackInnerTxRollbackPropagationNotSupport() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
                        "1111112");
                notSupportedTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus status) {
                        jdbcTemplate.update("insert into user (name, password) values (?, ?)",
                                "Huang", "1111112");
                    }
                });
                // 外部事务回滚,不会把内部的也连着回滚
                transactionStatus.setRollbackOnly();
            }
        });
    }
    @Override
    public void txRollbackInnerTxRollbackPropagationNotSupport2() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                try {
                    notSupportedTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                        @Override
                        protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                            jdbcTemplate.update("insert into user (name, password) values (?, ?)",
                                    "Huang", "1111112");
                            throw new CustomRuntimeException();
                        }
                    });
                } catch (CustomRuntimeException e) {
                }
            }
        });
    }

测试用例:

/**
     * PROPAGATION_NOT_SUPPORTED:不支持事务,
     * 外围的事务回滚不会导致它包含的内容回滚
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationNotSupport() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationNotSupport();
        Assert.assertEquals(2,springTxService.mysqlConnection());
    }
    /**
     * PROPAGATION_NOT_SUPPORTED:不支持事务,内部发生异常,外部捕获,都不会发生回滚
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationNotSupport2() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationNotSupport2();
        Assert.assertEquals(3,springTxService.mysqlConnection());
    }

3.6、PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

1   @Override
 2     public void txRollbackInnerTxRollbackPropagationNever() {
 3         neverTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
 4             @Override
 5             protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
 6                 jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
 7                         "1111112");
 8             }
 9         });
10     }
11 
12     @Override
13     public void txRollbackInnerTxRollbackPropagationNever2() {
14         transactionTemplate.execute(new TransactionCallbackWithoutResult() {
15             @Override
16             protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
17                 jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
18                         "1111112");
19                 neverTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
20                     @Override
21                     protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
22                         jdbcTemplate.update("insert into user (name, password) values (?, ?)",                                "Huang", "1111112");
                     }
                 });
            }
         });
     }
     @Override
     public void txRollbackInnerTxRollbackPropagationNever3() {
         neverTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
             protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                 jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
               neverTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                     protected void doInTransactionWithoutResult(TransactionStatus status) {
                         jdbcTemplate.update("insert into user (name, password) values (?, ?)",
                                 "Huang", "1111112");
                    }
                });
            }
        });
     }

View Code

测试代码:

/**
     * PROPAGATION_NEVER:不允许当前事务上下文中存在事务,如果没有,就正常执行
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationNever() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationNever();
        Assert.assertEquals(2,springTxService.mysqlConnection());
    }
    /**
     * PROPAGATION_NEVER:不允许当前事务上下文中存在事务,
     * 如果有,则抛出 {@link IllegalTransactionStateException}
     */
    @Test(expected = IllegalTransactionStateException.class)
    public void testTxRollbackInnerTxRollbackPropagationNever2() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationNever2();
    }
    /**
     * PROPAGATION_NEVER:不允许当前事务上下文中存在事务,
     * 当两个 NEVER 的嵌套在一起的时候,应该也是能够执行成功的。
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationNever3() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationNever3();
        Assert.assertEquals(3,springTxService.mysqlConnection());
    }


3.7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

@Override
    public void txRollbackInnerTxRollbackPropagationNested() {
        nestedTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
                        "1111112");
                nestedTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                        jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
                                "1111112");
                        // 内部事务设置了 rollbackOnly,外部事务应该不受影响,可以继续提交
                        transactionStatus.setRollbackOnly();
                    }
                });
            }
        });
    }
    @Override
    public void txRollbackInnerTxRollbackPropagationNested2() {
        nestedTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                jdbcTemplate.update("insert into user (name, password) values (?, ?)", "Huang",
                        "1111112");
                nestedTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                        jdbcTemplate.update("insert into user (name, password) values (?, ?)",
                                "Huang", "1111112");
                    }
                });
                // 外部事务设置了 rollbackOnly,内部事务应该也被回滚掉
                transactionStatus.setRollbackOnly();
            }
        });
    }

测试代码:

/**
     * PROPAGATION_NESTED:内部事务通过设置 {@link org.springframework.transaction.TransactionStatus#setRollbackOnly()} 来触发回滚,
     * 外部事务依旧可以不受影响,正常提交
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationNested() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationNested();
        Assert.assertEquals(2, springTxService.mysqlConnection());
    }
    /**
     * PROPAGATION_NESTED:外部事务通过设置 {@link org.springframework.transaction.TransactionStatus#setRollbackOnly()} 来触发回滚,由于
     * savepoint 在外部事务的开头,所以内部事务应该也会被一起回滚掉
     */
    @Test
    public void testTxRollbackInnerTxRollbackPropagationNested2() throws Exception {
        springTxService.txRollbackInnerTxRollbackPropagationNested2();
        Assert.assertEquals(1, springTxService.mysqlConnection());
    }
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
17天前
|
缓存 安全 Java
Spring高手之路26——全方位掌握事务监听器
本文深入探讨了Spring事务监听器的设计与实现,包括通过TransactionSynchronization接口和@TransactionalEventListener注解实现事务监听器的方法,并通过实例详细展示了如何在事务生命周期的不同阶段执行自定义逻辑,提供了实际应用场景中的最佳实践。
40 2
Spring高手之路26——全方位掌握事务监听器
|
18天前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
42 14
|
19天前
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
|
1月前
|
Java 开发者 Spring
Spring高手之路24——事务类型及传播行为实战指南
本篇文章深入探讨了Spring中的事务管理,特别是事务传播行为(如REQUIRES_NEW和NESTED)的应用与区别。通过详实的示例和优化的时序图,全面解析如何在实际项目中使用这些高级事务控制技巧,以提升开发者的Spring事务管理能力。
52 1
Spring高手之路24——事务类型及传播行为实战指南
|
23天前
|
JavaScript Java 关系型数据库
Spring事务失效的8种场景
本文总结了使用 @Transactional 注解时事务可能失效的几种情况,包括数据库引擎不支持事务、类未被 Spring 管理、方法非 public、自身调用、未配置事务管理器、设置为不支持事务、异常未抛出及异常类型不匹配等。针对这些情况,文章提供了相应的解决建议,帮助开发者排查和解决事务不生效的问题。
|
1月前
|
XML Java 数据库连接
Spring中的事务是如何实现的
Spring中的事务管理机制通过一系列强大的功能和灵活的配置选项,为开发者提供了高效且可靠的事务处理手段。无论是通过注解还是AOP配置,Spring都能轻松实现复杂的事务管理需求。掌握这些工具和最佳实践,能
47 3
|
2月前
|
Java BI API
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java PDF导出工具。
586 0
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
|
2月前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
221 2
|
2月前
|
Java 关系型数据库 MySQL
Spring事务失效,我总结了这7个主要原因
本文详细探讨了Spring事务在日常开发中常见的七个失效原因,包括数据库不支持事务、类不受Spring管理、事务方法非public、异常被捕获、`rollbackFor`属性配置错误、方法内部调用事务方法及事务传播属性使用不当。通过具体示例和源码分析,帮助开发者更好地理解和应用Spring事务机制,避免线上事故。适合所有使用Spring进行业务开发的工程师参考。
39 2
|
Java 应用服务中间件 数据库连接
Spring全家桶之Spring篇深度分析(一)
Spring 框架不局限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何 Java 应用都可以从 Spring 中受益。Spring 框架还是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术和框架的能力。
Spring全家桶之Spring篇深度分析(一)
下一篇
DataWorks