【问题标题】:Is it possible to not be in @Transaction state, when calling a function from a transacted function?从事务处理函数调用函数时,是否可以不处于 @Transaction 状态?
【发布时间】:2020-10-17 10:31:06
【问题描述】:

不知道如何写标题,但我使用的是 Spring boot,并且我有一个类似的功能:

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
    public Optional<List<SomeClass>> bulkInsert(List<SomeClass> models, boolean withRefresh) {
        int rowsInserted = someDao.bulkInsert(models).length;
        if (rowsInserted > 0 && withRefresh) {
            // I don't want the getLatest() function to operate in a transaction
            return Optional.of(getLatest(someValue, models.size())); 
        }
        return Optional.empty();
    };

    @Transactional(propagation = NOT_SUPPORTED)
    public List<SomeClass> getLatest(long someValue, int limit) {
        TransactionStatus status = TransactionAspectSupport.currentTransactionStatus(); ### says the transaction is active
        return someDao.getLatest(accountId, limit);
    };

基本上我想从事务中排除 getLatest() 。有可能吗?

【问题讨论】:

  • “从交易中排除”到底是什么意思?在您当前的代码中,当您在内部调用“getLatest”时,@Transactional(propagation = NOT_SUPPORTED) 未应用且完全无用。
  • 我想你已经在下面回答了我想知道的问题。我将插入包装在手动事务中,删除了@Transactional,并在事务完成后放置 getLatest。全部使用 TransactionTemplate。

标签: java spring-boot transactions spring-data spring-transactions


【解决方案1】:

改用这个:

 @Transactional(propagation = NOT_SUPPORTED)
    public List<SomeClass> getLatest(long someValue, int limit) {

有关传播级别的说明,请参阅Spring Propagation Doc

【讨论】:

    【解决方案2】:

    如果您只想将事务用于

    someDao.bulkInsert(models).length;
    

    那么您应该将此代码与事务方面一起包装并单独调用另一部分。像这样:

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
    public int bulkInsert(List<SomeClass> models, boolean withRefresh) {
       return  someDao.bulkInsert(models).length;
    }
    
    public Optional<List<SomeClass>> abc(int rowInserted, boolean withRefresh){
        if (rowsInserted > 0 && withRefresh) {
           return Optional.of(getLatest(someValue, models.size())); ### I don't want the getLatest() function to operate in a transaction
        }
    
        return Optional.empty();
    } 
    
    public List<SomeClass> getLatest(long someValue, int limit) {
      TransactionStatus status = TransactionAspectSupport.currentTransactionStatus(); ### says the transaction is active
      return someDao.getLatest(accountId, limit);
    };
    

    最重要的是,您需要从该实例外部调用此方法。

    对于您在标题中的问题:不,您不能在事务之外获取一些代码,因为 spring-aop 使用代理并且整个方法在代理实例中以事务方面包装。

    【讨论】:

    • 事情是我不想将 insert/getLatest 彼此分开,但如果我愿意,这将是一个很好的方法。或者只是从控制器调用 getLatest,甚至不使用 'withLatest'。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    • 2016-09-30
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    相关资源
    最近更新 更多