精华内容
下载资源
问答
  • 主要介绍了spring的@Transactional注解用法解读,具有一定借鉴价值,需要的朋友可以参考下
  • 主要介绍了Spring @Transactional注解失效解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • @Transactional 事务实现机制 在应用系统调用声明了@Transactional的目标方法时,Spring Framework 默认使用 AOP 代理,在代码运行时生成一个代理对象,根据@Transactional的属性配置信息,这个代理对象决定该声明@...

    @Transactional 事务实现机制

    在应用系统调用声明了 @Transactional 的目标方法时,Spring Framework 默认使用 AOP 代理,在代码运行时生成一个代理对象,根据 @Transactional 的属性配置信息,这个代理对象决定该声明 @Transactional 的目标方法是否由拦截器 TransactionInterceptor 来使用拦截,在 TransactionInterceptor 拦截时,会在目标方法开始执行之前创建并加入事务,并执行目标方法的逻辑, 最后根据执行情况是否出现异常,利用抽象事务管理器 AbstractPlatformTransactionManager 操作数据源 DataSource 提交或回滚事务。

     

    场景一:同一个service中,父方法调用了子方法都使用了@Transactional方法,则父方法发生异常时会整体回滚:

    官方解释如下:

    In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.

    大概意思:在默认的代理模式下,只有目标方法由外部调用,才能被 Spring 的事务拦截器拦截。在同一个类中的两个方法直接调用,是不会被 Spring 的事务拦截器拦截,就像上面的 save 方法直接调用了同一个类中的 method1方法,method1 方法不会被 Spring 的事务拦截器拦截。

     

    场景二:一个父方法中包含了多个子方法,如发生异常无需回滚异常前执行结果的情况,则需要将子方法写入一个新的service,并将子方法@Transactional 的 propagation 属性设置为 Propagation.REQUIRES_NEW。

    这样父方法的执行过程变更为:

    首先创建了 父方法 的事务,执行到子方法,暂停了 save 方法的事务,重新创建了 子方法 的事务,接着 子方法 的事务提交,之后发生异常, 父方法 的事务回滚。

     

    原文链接:https://blog.csdn.net/nextyu/article/details/78669997 

    本文根据博主个人需要整理保留个人理解部分。

     

     

    展开全文
  • @Transactional注解使用

    2019-10-21 16:25:23
    @Transactional注解 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。 虽然@...

    1.1 @Transactional介绍

           @Transactional注解 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。

           虽然@Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional注解应该只被应用到 public 方法上,这是由Spring AOP的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

           默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。

    1.2 @Transactional注解属性

           @Transactional注解里面的各个属性和咱们在上面讲的事务属性里面是一一对应的。用来设置事务的传播行为、隔离规则、回滚规则、事务超时、是否只读。

    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface Transactional {
    
        /**
         * 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
         */
        @AliasFor("transactionManager")
        String value() default "";
    
        /**
         * 同上。
         */
        @AliasFor("value")
        String transactionManager() default "";
    
        /**
         * 事务的传播行为,默认值为 REQUIRED。
         */
        Propagation propagation() default Propagation.REQUIRED;
    
        /**
         * 事务的隔离规则,默认值采用 DEFAULT。
         */
        Isolation isolation() default Isolation.DEFAULT;
    
        /**
         * 事务超时时间。
         */
        int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
    
        /**
         * 是否只读事务
         */
        boolean readOnly() default false;
    
        /**
         * 用于指定能够触发事务回滚的异常类型。
         */
        Class<? extends Throwable>[] rollbackFor() default {};
    
        /**
         * 同上,指定类名。
         */
        String[] rollbackForClassName() default {};
    
        /**
         * 用于指定不会触发事务回滚的异常类型
         */
        Class<? extends Throwable>[] noRollbackFor() default {};
    
        /**
         * 同上,指定类名
         */
        String[] noRollbackForClassName() default {};
    
    }
    

    1.2.1 value、transactionManager属性

           它们两个是一样的意思。当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器。大多数项目只需要一个事务管理器。然而,有些项目为了提高效率、或者有多个完全不同又不相干的数据源,从而使用了多个事务管理器。机智的Spring的Transactional管理已经考虑到了这一点,首先定义多个transactional manager,并为qualifier属性指定不同的值;然后在需要使用@Transactional注解的时候指定TransactionManager的qualifier属性值或者直接使用bean名称。配置和代码使用的例子:

    <tx:annotation-driven/>
     
    <bean id="transactionManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource1"></property>
        <qualifier value="datasource1Tx"/>
    </bean>
     
    <bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource2"></property>
        <qualifier value="datasource2Tx"/>
    </bean>
    
    public class TransactionalService {
     
        @Transactional("datasource1Tx")
        public void setSomethingInDatasource1() { ... }
     
        @Transactional("datasource2Tx")
        public void doSomethingInDatasource2() { ... }
    
    }
    

    1.2.2 propagation属性

           propagation用于指定事务的传播行为,默认值为 REQUIRED。propagation有七种类型,就是我们在上文中讲到的事务属性传播行为的七种方式,如下所示:

    propagation属性事务属性-传播行为含义
    REQUIREDTransactionDefinition.PROPAGATION_REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事务,则加入到这个事务中。这是最常见的选择。
    SUPPORTSTransactionDefinition.PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行。
    MANDATORYTransactionDefinition.PROPAGATION_MANDATORY表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常。
    REQUIRES_NEWTransactionDefinition.PROPAGATION_REQUIRES_NEW表示当前方法必须运行在它自己的事务中。一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。
    NOT_SUPPORTEDTransactionDefinition.PROPAGATION_NOT_SUPPORTED表示该方法不应该运行在事务中。如果当前存在事务,就把当前事务挂起。
    NEVERTransactionDefinition.PROPAGATION_NEVER表示当前方法不应该运行在事务上下文中。如果当前正有一个事务在运行,则会抛出异常。
    NESTEDTransactionDefinition.PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

    1.2.3 isolation属性

           isolation用于指定事务的隔离规则,默认值为DEFAULT。@Transactional的隔离规则和上文事务属性里面的隔离规则也是一一对应的。总共五种隔离规则,如下所示:

    @isolation属性事务属性-隔离规则含义脏读不可重复读幻读
    DEFAULTTransactionDefinition.ISOLATION_DEFAULT使用后端数据库默认的隔离级别  
    READ_UNCOMMITTEDTransactionDefinition.ISOLATION_READ_UNCOMMITTED允许读取尚未提交的数据变更(最低的隔离级别)
    READ_COMMITTEDTransactionDefinition.ISOLATION_READ_COMMITTED允许读取并发事务已经提交的数据
    REPEATABLE_READTransactionDefinition.ISOLATION_REPEATABLE_READ对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改
    SERIALIZABLETransactionDefinition.ISOLATION_SERIALIZABLE最高的隔离级别,完全服从ACID的隔离级别,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现的

    1.2.4 timeout

           timeout用于设置事务的超时属性。

    1.2.5 readOnly

           readOnly用于设置事务是否只读属性。

    1.2.6 rollbackFor、rollbackForClassName、noRollbackFor、noRollbackForClassName

           rollbackFor、rollbackForClassName用于设置那些异常需要回滚;noRollbackFor、noRollbackForClassName用于设置那些异常不需要回滚。他们就是在设置事务的回滚规则。

    1.3 @Transactional注解的使用

           @Transactional注解的使用关键点在理解@Transactional注解里面各个参数的含义。这个咱们在上面已经对@Transactional注解参数的各个含义做了一个简单的介绍。接下来,咱们着重讲一讲@Transactional注解使用过程中一些注意的点。

           @Transactional注解内部实现依赖于Spring AOP编程。而AOP在默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为。

    1.3.1 @Transactional 注解尽量直接加在方法上

           为什么:因为@Transactional直接加在类或者接口上,@Transactional注解会对类或者接口里面所有的public方法都有效(相当于所有的public方法都加上了@Transactional注解,而且注解带的参数都是一样的)。第一影响性能,可能有些方法我不需要@Transactional注解,第二方法不同可能@Transactional注解需要配置的参数也不同,比如有一个方法只是做查询操作,那咱们可能需要配置Transactional注解的readOnly参数。所以强烈建议@Transactional注解直接添加的需要的方法上。

    1.3.2 @Transactional 注解必须添加在public方法上,private、protected方法上是无效的

           在使用@Transactional 的时候一定要记住,在private,protected方法上添加@Transactional 注解不会有任何效果。相当于没加一样。即使外部能调到protected的方法也无效。和没有添加@Transactional一样。

    1.3.3 函数之间相互调用

           关于有@Transactional的函数之间调用,会产生什么情况。这里咱们通过几个例子来说明。

    2.3.3.1 同一个类中函数相互调用

           同一个类AClass中,有两个函数aFunction、aInnerFunction。aFunction调用aInnerFunction。而且aFunction函数会被外部调用。

    情况0: aFunction添加了@Transactional注解,aInnerFunction函数没有添加。aInnerFunction抛异常。

    public class AClass {
    
        @Transactional(rollbackFor = Exception.class)
        public void aFunction() {
            //todo: 数据库操作A(增,删,该)
            aInnerFunction(); // 调用内部没有添加@Transactional注解的函数
        }
    
        private void aInnerFunction() {
            //todo: 操作数据B(做了增,删,改 操作)
            throw new RuntimeException("函数执行有异常!");
        }
    
    }
    

           结果:两个函数操作的数据都会回滚。

    情况1:两个函数都添加了@Transactional注解。aInnerFunction抛异常。

    public class AClass {
    
        @Transactional(rollbackFor = Exception.class)
        public void aFunction() {
            //todo: 数据库操作A(增,删,该)
            aInnerFunction(); // 调用内部没有添加@Transactional注解的函数
        }
    
        @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
        private void aInnerFunction() {
            //todo: 操作数据B(做了增,删,改 操作)
            throw new RuntimeException("函数执行有异常!");
        }
    
    }
    

           结果:同第一种情况一样,两个函数对数据库操作都会回滚。因为同一个类中函数相互调用的时候,内部函数添加@Transactional注解无效。@Transactional注解只有外部调用才有效。

    情况2: aFunction不添加注解,aInnerFunction添加注解。aInnerFunction抛异常。

    public class AClass {
    
        public void aFunction() {
            //todo: 数据库操作A(增,删,该)
            aInnerFunction(); // 调用内部没有添加@Transactional注解的函数
        }
    
        @Transactional(rollbackFor = Exception.class)
        protected void aInnerFunction() {
            //todo: 操作数据B(做了增,删,改 操作)
            throw new RuntimeException("函数执行有异常!");
        }
    
    }
    

           结果:两个函数对数据库的操作都不会回滚。因为内部函数@Transactional注解添加和没添加一样。

    情况3:aFunction添加了@Transactional注解,aInnerFunction函数没有添加。aInnerFunction抛异常,不过在aFunction里面把异常抓出来了。

    public class AClass {
    
        @Transactional(rollbackFor = Exception.class)
        public void aFunction() {
            //todo: 数据库操作A(增,删,该)
            try {
                aInnerFunction(); // 调用内部没有添加@Transactional注解的函数
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private void aInnerFunction() {
            //todo: 操作数据B(做了增,删,改 操作)
            throw new RuntimeException("函数执行有异常!");
        }
    
    }
    

           结果:两个函数里面的数据库操作都成功。事务回滚的动作发生在当有@Transactional注解函数有对应异常抛出时才会回滚。(当然了要看你添加的@Transactional注解有没有效)。

    1.3.3.1. 不同类中函数相互调用

           两个类AClass、BClass。AClass类有aFunction、BClass类有bFunction。AClass类aFunction调用BClass类bFunction。最终会在外部调用AClass类的aFunction。

    情况0:aFunction添加注解,bFunction不添加注解。bFunction抛异常。

    @Service()
    public class AClass {
    
        private BClass bClass;
    
        @Autowired
        public void setbClass(BClass bClass) {
            this.bClass = bClass;
        }
    
        @Transactional(rollbackFor = Exception.class)
        public void aFunction() {
            //todo: 数据库操作A(增,删,该)
            bClass.bFunction();
        }
    
    }
    
    @Service()
    public class BClass {
    
        public void bFunction() {
            //todo: 数据库操作A(增,删,该)
            throw new RuntimeException("函数执行有异常!");
        }
    }
    

           结果:两个函数对数据库的操作都回滚了。

    情况1:aFunction、bFunction两个函数都添加注解,bFunction抛异常。

    @Service()
    public class AClass {
    
        private BClass bClass;
    
        @Autowired
        public void setbClass(BClass bClass) {
            this.bClass = bClass;
        }
    
        @Transactional(rollbackFor = Exception.class)
        public void aFunction() {
            //todo: 数据库操作A(增,删,该)
            bClass.bFunction();
        }
    
    }
    
    @Service()
    public class BClass {
    
        @Transactional(rollbackFor = Exception.class)
        public void bFunction() {
            //todo: 数据库操作A(增,删,该)
            throw new RuntimeException("函数执行有异常!");
        }
    }
    

           结果:两个函数对数据库的操作都回滚了。两个函数里面用的还是同一个事务。这种情况下,你可以认为事务rollback了两次。两个函数都有异常。

    情况2:aFunction、bFunction两个函数都添加注解,bFunction抛异常。aFunction抓出异常。

    @Service()
    public class AClass {
    
        private BClass bClass;
    
        @Autowired
        public void setbClass(BClass bClass) {
            this.bClass = bClass;
        }
    
        @Transactional(rollbackFor = Exception.class)
        public void aFunction() {
            //todo: 数据库操作A(增,删,该)
            try {
                bClass.bFunction();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
    @Service()
    public class BClass {
    
        @Transactional(rollbackFor = Exception.class)
        public void bFunction() {
            //todo: 数据库操作A(增,删,该)
            throw new RuntimeException("函数执行有异常!");
        }
    }
    

           结果:两个函数数据库操作都没成功。而且还抛异常了。org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only。看打印出来的解释也很好理解把。咱们也可以这么理解,两个函数用的是同一个事务。bFunction函数抛了异常,调了事务的rollback函数。事务被标记了只能rollback了。程序继续执行,aFunction函数里面把异常给抓出来了,这个时候aFunction函数没有抛出异常,既然你没有异常那事务就需要提交,会调事务的commit函数。而之前已经标记了事务只能rollback-only(以为是同一个事务)。直接就抛异常了,不让调了。

    情况3:aFunction、bFunction两个函数都添加注解,bFunction抛异常。aFunction抓出异常。这里要注意bFunction函数@Transactional注解我们是有变化的,加了一个参数propagation = Propagation.REQUIRES_NEW,控制事务的传播行为。表明是一个新的事务。其实咱们情况3就是来解决情况2的问题的。

    @Service()
    public class AClass {
    
        private BClass bClass;
    
        @Autowired
        public void setbClass(BClass bClass) {
            this.bClass = bClass;
        }
    
        @Transactional(rollbackFor = Exception.class)
        public void aFunction() {
            //todo: 数据库操作A(增,删,该)
            try {
                bClass.bFunction();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
    @Service()
    public class BClass {
    
        @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
        public void bFunction() {
            //todo: 数据库操作A(增,删,该)
            throw new RuntimeException("函数执行有异常!");
        }
    }
    

           结果:bFunction函数里面的操作回滚了,aFunction里面的操作成功了。有了前面情况2的理解。这种情况也很好解释。两个函数不是同一个事务了。


         总结:

    1. 要知道@Transactional注解里面每个属性的含义。@Transactional注解属性就是来控制事务属性的。通过这些属性来生成事务。

    2. 要明确我们添加的@Transactional注解会不会起作用。@Transactional注解在外部调用的函数上才有效果,内部调用的函数添加无效,要切记。这是由AOP的特性决定的。

    3. 要明确事务的作用范围,有@Transactional的函数调用有@Transactional的函数的时候,进入第二个函数的时候是新的事务,还是沿用之前的事务。稍不注意就会抛UnexpectedRollbackException异常。

    展开全文
  • @Transactional注解作用

    千次阅读 2020-08-21 13:13:09
    @Transactional是spring中常用的注解之一,通常情况下我们在需要对一个service方法添加事务时,加上这个注解,如果发生unchecked exception,就会发生rollback MyBatis自动参与到spring事务管理中,无需额外配置,...

    一、介绍

    @Transactional是spring中常用的注解之一,通常情况下我们在需要对一个service方法添加事务时,加上这个注解,如果发生unchecked exception,就会发生rollback

    MyBatis自动参与到spring事务管理中,无需额外配置,只要org.mybatis.spring.SqlSessionFactoryBean引用的数据源与DataSourceTransactionManager引用的数据源一致即可,否则事务管理会不起作用。

    二、@Transactional 注解的属性信息

    @Transactional**属性

    属性类型描述
    valueString可选的限定描述符,指定使用的事务管理器
    propagationenum: Propagation可选的事务传播行为设置
    isolationenum: Isolation可选的事务隔离级别设置
    readOnlyboolean读写或只读事务,默认读写
    timeoutint (in seconds granularity)事务超时时间设置
    rollbackForClass对象数组,必须继承自Throwable导致事务回滚的异常类数组
    rollbackForClassName类名数组,必须继承自Throwable导致事务回滚的异常类名字数组
    noRollbackForClass对象数组,必须继承自Throwable不会导致事务回滚的异常类数组
    noRollbackForClassName类名数组,必须继承自Throwable不会导致事务回滚的异常类名字数组

    三、@Transactional 注解的属性信息用法

    @Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。

    虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。但是这个被注解的方法将不会展示已配置的事务设置。

    默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。

    @Transactional(readOnly = true)
    public class DefaultFooService implements FooService {
    
      public Foo getFoo(String fooName) {
        // do something
      }
    
      // these settings have precedence for this method
      //方法上注解属性会覆盖类注解上的相同属性
      @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
      public void updateFoo(Foo foo) {
        // do something
      }
    }
    
    展开全文
  • @Transactional可以说是spring中最常用的注解之一了,通常情况下我们在需要对一个service方法添加事务时,加上这个注解,如果发生unchecked exception,就会发生rollback,最典型的例子如下。 @Service public class...

    @Transactional可以说是spring中最常用的注解之一了,通常情况下我们在需要对一个service方法添加事务时,加上这个注解,如果发生unchecked exception,就会发生rollback,最典型的例子如下。

    @Service
    public class StudentService {
        @Autowired
        StudentDao studentDao;
    
        @Transactional
        public void innerSave(int i) {
            Student student = new Student();
            student.setName("test" + i);
            studentDao.save(student);
            //i=5 会出现异常
            int a = 1 / (i - 5);
        }
    }

    在调用innerSave(5)时会发运算异常,导致保存操作回滚,不在此赘述了。
    新的需求:循环保存10个学生,发生异常时要求回滚。
    我们理所当然的写出了下面的代码,在StudentService.java添加如下方法

    public void outerLooper1() {
           for (int i = 1; i <= 10; i++) {
               try{
                   innerSave(i);
               }catch (Exception e){
                   e.printStackTrace();
               }
           }
       }

    先考虑一下test5这个学生有没有保存呢?
    结果:
    在这里插入图片描述
    依然出现了,考虑下问题出在哪儿了?
    其实也好理解,spring中@Transactional 的事务开启 ,是基于接口 或者是类的代理被创建的。所以在同一个类中一个普通方法outerLooper1()调用另一个有事务的方法innerSave(),事务是不会起作用的。要解决这个问题,一般我的做法是写一个帮助类,注入到当前类中,来完成事务操作。

        @Autowired
        UtilService utilService;
    
        public void outerLooper2() {
            for (int i = 1; i <= 10; i++) {
                utilService.innerSave(i);
            }
        }

    在这里插入图片描述
    在spring中使用事务需要遵守一些规范和了解一些坑点,别想当然。列举一下一些注意点。

    • 在需要事务管理的地方加@Transactional 注解。@Transactional 注解可以被应用于接口定义和接口方法、类定义和类的public 方法上。@Transactional 注解只能应用到 public 可见度的方法上。如果你在 protected、private 或者package-visible 的方法上使用@Transactional 注解,它也不会报错,但是这个被注解的方法将不会展示已配置的事务设置。
    • Spring团队建议在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。在接口上使用@Transactional 注解,只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。
    • @Transactional 的事务开启 ,或者是基于接口的或者是基于类的代理被创建。所以在同一个类中一个方法调用另一个方法有事务的方法,事务是不会起作用的。
    • 了解事务的隔离级别,各个数据库默认的隔离级别是不一样的,在spring中用的是isolation =
      Isolation.READ_COMMITTED来设置;了解事务的传播机制,当发生事务嵌套时,按照业务选择对应的传播机制,用propagation
      = Propagation.REQUIRED来设置。
    展开全文
  • 引言@Transactional注解相信大家并不陌生,平时开发中很常用的一个注解,它能保证方法内多个数据库操作要么同时成功、要么同时失败。使用@Transactional注解时需要注意许多的细节,不然你会发现@Transactional总是...
  • 引言@Transactional注解哪些场景下会失效,一时语塞致使面试失败。所以今天简单的和大家分享一下@Transactional相关的知识。@Transactional 注解相信大家并不陌生,平时开发中很常用的一个注解,它能保证方法内多个...
  • 主要介绍了Java注解@Transactional事务类内调用不生效问题及解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • @Transactional注解可以作用于接口、接口方法、类以及类方法上 当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性 当作用在方法级别时会覆盖类级别的定义 当作用在接口和接口方法时则只有在...
  • @Modifying注解和@Transactional注解

    千次阅读 2020-01-11 20:56:30
    JPA中自定义的插入、更新、删除方法为什么要添加@Modifying注解和@Transactional注解?  前几天,有个同事在使用JPA的自定义SQL方法时,程序一直报异常,捣鼓了半天也没能解决,咨询我的时候,我看了一眼他的程序,...
  • 引言昨天朋友咨询了一个问题,说自己之前面试被问@Transactional注解哪些场景下会失效,一时语塞致使面试失败。所以今天简单的和大家分享一下@Transactional相关的知识。@Transactional 注解相信大家并不陌生,平时...
  • 1,场景一,最常见的用法,在方法上使用@Transactional 注解,事务正常起作用。无异常时正常插入数据库,有异常时数据不插入数据库,代码如下。 @Service public class ComeServiceImpl implements ComeService { ...
  • @Transactional注解不起作用解决办法及原理分析

    万次阅读 多人点赞 2018-12-09 00:21:50
    Transactional注解标注方法修饰符为非public时,@Transactional注解将会不起作用。例如以下代码。 定义一个错误的@Transactional标注实现,修饰一个默认访问符的方法 /** * @author zhoujy * @date 2018年12月06日...
  • 解释@Transactional注解的用法

    万次阅读 多人点赞 2019-07-17 10:41:55
    @Transactional可以说是spring中最常用的注解之一了,通常情况下我们在需要对一个service方法添加事务时,加上这个注解,如果发生unchecked exception,就会发生rollback,最典型的例子如下。 @Service public class...
  • 若同一类中的其他没有@Transactional 注解的方法内部调用有@Transactional 注解的方法,有@Transactional 注解的方法的事务被忽略,不会发生回滚。见清单 5 举例代码展示。 自调用问题举例 @Service -->public class...
  • 主要介绍了Spring @Transactional工作原理详解,具有一定借鉴价值,需要的朋友可以参考下。
  • @Transactional public void updateData(){  aService.updateA();//更新A表  bService.updateB();//更新B表  cService.updateC();//更新C表 } 假设,如果每一个service只会对应的更新他所对应的这张表,...
  • 文章目录 1.美图 2. 源码 3.@Transactional 注解的属性信息 4.... 案例 6.1 基于tx标签的声明式事物 参考:基于tx标签的声明式事物 6.2 基于@Transactional注解的声明式事物 参考:基于@Transactional注解的声明式事物
  • @Transactional注解

    2021-03-24 09:28:42
    @Transactional 是声明式事务编程中使用的注解。 事务注解会让一个方法在执行之后,哟啊么提交所有的改变,要么什么都不改变,ACID原则 (原子性,一致性,隔离性,持续性) 添加在接口的实现类上,或者接口的实现...
  • 使用@Transactional注解时需要注意许多的细节,不然你会发现@Transactional总是莫名其妙的就失效了。 一、事务 事务管理在系统开发中是不可缺少的一部分,Spring提供了很好事务管理机制,主要分为编程式事务和声明...
  • 目录什么是注解注解的基本元素元注解@TargetRetention自定义注解实现声明注解改造demo测试 什么是注解 注解可以用来修饰类,方法,属性等,可以看做是一个特殊的标记,程序在编译或运行时检测到这些标记,从而进行...
  • @Transactional注解的失效场景

    千次阅读 2020-04-16 10:17:01
    二、@Transactional介绍 1、@Transactional注解可以作用于哪些地方? @Transactional 可以作用在接口、类、类方法 作用于类:当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性...
  • 作者:程序员内点事引言昨天公众号粉丝咨询了一个问题,说自己之前面试被问@Transactional注解哪些场景下会失效,一时语塞致使面试失败。所以今天简单的和大家分享一下@Transactional相关的知识。@Transactional ...
  • 通过本篇学习,你将加深对@Transactional 注解以及所有的属性的理解,还可以学习到@Transactional 注解常见的失效场景【文章最后】。
  • 使用@Transactional注解时需要注意许多的细节,不然你会发现@Transactional总是莫名其妙的就失效了。 一、事务 事务管理在系统开发中是不可缺少的一部分,Spring提供了很好事务管理机制,主要分为编程式事务和声明...
  • @Transactional注解详细使用

    万次阅读 2020-06-17 11:33:03
    三、开发案例 workflow服务: payment服务添加注解:回滚所有的异常。 workflow调用payment服务的saveTransactionDatasBatch方法:
  • 引言昨天公众号粉丝咨询了一个问题,说自己之前面试被问@Transactional注解哪些场景下会失效,一时语塞致使面试失败。所以今天简单的和大家分享一下@Transactional相关的...
  • @Transactional注解的使用: 1、在方法或者类上都可以添加。(如果在类上添加,则此类中的所有方法都会执行事务,不推荐,因为可能后续接手开发的小伙伴添加方法的时候根本不需要执行事务); 2、触发事务回滚有两...
  • @Transactional 注解 它能保证方法内多个数据库操作要么同时成功、要么同时失败。 事务方面:主要分为2种 1.编程式事务 2.声明式事务 1.手动指定: try { //TODO something transactionManager.commit...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 51,331
精华内容 20,532
关键字:

@transactional注解的作用