当前位置: 首页 > 面试题库 >

了解Spring事务边界

夏学名
2023-03-14
问题内容

我正在尝试通过以下示例来消除我对Spring Transaction边界的怀疑。

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void test() {    
    test1();
    test2();        
}

@Transactional(propagation=Propagation.NOT_SUPPORTED, readOnly=false)
public void test1() {
    this.jdbcTemplate.execute("INSERT INTO TEST VALUES('T', 'C2', 0, 1)");      
}

@Transactional(propagation=Propagation.SUPPORTS, isolation=Isolation.READ_UNCOMMITTED, readOnly=true)
public void test2() {
    System.out.println(this.jdbcTemplate.queryForInt("select count(*) from TEST"));         
}

我想将test2()方法与test1()隔离开,即每次调用test()时,test2()都不应读取test1()提交的数据。请建议是否可以使用传播或隔离属性来处理这种情况。

提前致谢。


问题答案:

html" target="_blank">事务属性应用于外部调用,而不是由bean方法(例如您的案例)进行的内部调用。如果要将事务边界应用于调用,则应注入如下所示的bean实例。但是我认为这不是一个好习惯,我不建议这样做。正确的方法是定义另一个spring
bean,并将其与您以前的bean关联,然后将测试方法放入该新bean。

@Service("yourBean")
@Transactional
public class YourBeanClass implement IYourBean {

   @Resource(name="yourBean")
    IYourBean yourBean;

        @Transactional(propagation=Propagation.REQUIRED)
    public void test() {    
        yourBean.test1();
        yourBean.test2();       
    }

    @Transactional(propagation=Propagation.REQUIRED)
    public void test1() {
        this.jdbcTemplate.execute("INSERT INTO TEST VALUES('T', 'C2', 0, 1)");      
    }

    @Transactional(propagation=Propagation.NOT_SUPPORTED)
    public void test2() {
        System.out.println(this.jdbcTemplate.queryForInt("select count(*) from TEST"));         
    }

}

解决这个特殊问题的替代的更好的方法;

 @Service("otherBean")
    @Transactional
    public class OtherBeanClass implement IOtherBean {

     @Autowired
     IYourBean yourBean;

      @Transactional(propagation=Propagation.REQUIRED)
        public void test() {    
            yourBean.test1();
            yourBean.test2();       
        }

   }



    @Service("yourBean")
    @Transactional
    public class YourBeanClass implement IYourBean {



        @Transactional(propagation=Propagation.REQUIRED)
        public void test1() {
            this.jdbcTemplate.execute("INSERT INTO TEST VALUES('T', 'C2', 0, 1)");      
        }

        @Transactional(propagation=Propagation.NOT_SUPPORTED)
        public void test2() {
            System.out.println(this.jdbcTemplate.queryForInt("select count(*) from TEST"));         
        }
}


 类似资料:
  • 问题内容: 在PHP文件说: 如果您以前从未遇到过事务,则它们提供4个主要功能:原子性,一致性,隔离性和持久性(ACID)。用外行的术语来说,事务中执行的任何工作,即使它是分阶段进行的,都可以保证在提交时安全地应用于数据库,并且不受其他连接的干扰。 题: 这是否意味着我可以让两个单独的php脚本同时运行事务,而又彼此不干扰? 通过 “ 干扰 ” 细化我的 意思 : 假设我们有下表: 如果我有两个脚

  • 本文向大家介绍简单了解Spring中的事务控制,包括了简单了解Spring中的事务控制的使用技巧和注意事项,需要的朋友参考一下 1.事务的概念 事务是一组操作的执行单元,相对于数据库的单条操作而言,事务管理的是一组SQL指令,如增删改查等,事务的特性体现在事务内包含的SQL指令必须全部执行成功,如果其中一条指令发生错误,那么整个事务内的一组操作都要进行回滚。 事务有四个特性: 原子性 Atomic

  • 我正在使用spring boot和hibernate over jpa以及tomcat连接池。您能帮助我理解spring在事务期间如何使用DB连接吗。例如,考虑以下场景: 我们有2个连接的DB连接池 Spring启动一个事务,即用@Transactional注释修饰的调用方法 此方法执行数据库更新 呼叫外部服务 当从外部服务接收到响应时,它更新DB并返回 Spring提交事务 假设外部服务(步骤4

  • 我们正在将图形ql-spqr和图形ql-spqr-Spring启动器用于一个新项目(使用Spring数据JPA,Hibernate等)。 我们有这样一个突变: 这种突变工作正常: 我忽略了变量,因为它们不重要。如果我将其更改为: 我收到LazyInitalizationException,我知道原因: 家庭团队由一个ID引用,并由加载。返回的团队只是一个Hibernate代理。这对于保存新的匹配很

  • 问题内容: 为了了解Spring事务的工作原理,我想知道在以下情况下会发生什么情况,其中一种方法标记为,而另一种方法标记为。 假设配置使用所有默认设置。 现在,如果我要输入,显然可以开始交易。然后,钻进去会发生什么?事务已经存在的事实会导致没有新的事务诞生,还是我在这里创建两个事务? 关于传播的文档(在下面引用)似乎涵盖了这一点,但是我想验证一下我的理解,这对于我的处女大脑来说可以一次理解所有知识

  • 我有一个关于ApacheCamel的问题。我无法找到多播是否被事务处理。如果它被事务处理,事务是如何实现的?事务边界是什么?