【问题标题】:Number of transactions using @transactional in Spring Mvc [closed]在 Spring Mvc 中使用 @transactional 的事务数 [关闭]
【发布时间】:2015-09-24 11:57:09
【问题描述】:

我是 spring-mvc-hibernate 的初学者,我有一个控制器,它在我的 spring mvc 中有许多对 daoimpl 方法的调用,这些方法由 @Transactional 注释它是为每个方法进行往返还是只做一个?

代码如下:Hibernate 用于处理所有调用

CustomerEntity customerEntity = (CustomerEntity) customerService.getCustomerFromLeadId(id);
AddressEntity resAddressEntity = (AddressEntity) addressService.getResAddress(customerEntity.getSomeId());
AddressEntity offAddressEntity = (AddressEntity) addressService.getOffAddress(customerEntity.getSomeId());
List<KeyContactsEntity> listKeyContacts = keyContactService.getKeyContactOfClient(customerEntity.getSomeId());
List<PropertyEntity> listProperty = propertyService.getListOfProperty(customerEntity.getSomeId()) ;
customerDto = masterService.setEntityValues(customerDto,customerEntity,resAddressEntity,offAddressEntity,listKeyContacts,listProperty);

【问题讨论】:

  • 往返?往返哪里?所有带注释的方法都会自然地开始(并完成)它们自己的事务。
  • 事务不会神奇地将完全不同的查询组合成一个查询。

标签: java spring hibernate model-view-controller transactional


【解决方案1】:

默认情况下,只会使用一笔交易。

您可以在此处阅读交易传播以完全理解:

Spring transaction propagation

默认情况下,Spring 将使用“必需”策略,即“支持当前事务,如果不存在则创建一个新事务”。还有许多其他策略可以满足您的需求。

一个典型的“陷阱”:Spring 事务管理是基于代理的,因此它只会在您调用位于另一个类而不是调用者的方法时触发,即当您调用同一类上的方法时不会触发事务。

【讨论】:

    【解决方案2】:

    交易的运作方式很简单。如果从组件控制器(非事务性)调用来自服务的方法(即事务性),则您的服务方法创建事务,然后当方法完成时,由于您的控制器不是事务性的,事务完成并且它承诺。

    因此,在您从非事务性组件调用所有这些服务的情况下,您会为每个错误的服务创建一个新事务,因为这意味着如果第三个服务出现问题,您将无法回滚前两个

    class Controller {
    
        //New transaction
        CustomerEntity customerEntity = (CustomerEntity) customerService.getCustomerFromLeadId(id);
        //New transaction
        AddressEntity resAddressEntity = (AddressEntity) addressService.getResAddress(customerEntity.getSomeId());
        //New transaction
        AddressEntity offAddressEntity = (AddressEntity) addressService.getOffAddress(customerEntity.getSomeId());
        //New transaction / if something goes wrong no rollback for previous transactions
        List<KeyContactsEntity> listKeyContacts = keyContactService.getKeyContactOfClient(customerEntity.getSomeId());
    
    }
    

    如果您想将所有服务事务组合成一个,则需要使用 @Transaction 将它们全部包装到“外观”组件中

       @Transactional
       class FacadeService {
    
        //New transaction
        CustomerEntity customerEntity = (CustomerEntity) customerService.getCustomerFromLeadId(id);
        //Reuse transaction
        AddressEntity resAddressEntity = (AddressEntity) addressService.getResAddress(customerEntity.getSomeId());
        //Reuse transaction
        AddressEntity offAddressEntity = (AddressEntity) addressService.getOffAddress(customerEntity.getSomeId());
        //Reuse transaction / If something goes wrong rollback of everyting
        List<KeyContactsEntity> listKeyContacts = keyContactService.getKeyContactOfClient(customerEntity.getSomeId());
    
    }
    

    【讨论】:

    • 我提到的所有方法都在daoImpl中用@transactional注解。我正在做的是我调用的方法都是内部调用dao方法并返回数据的服务方法。那么在这种情况下,每个方法都会往返于 db 还是所有数据都将在一个 db 事务中获取?
    • k..k..我明白了...谢谢!!!
    • 如果答案有用,请投票并将其标记为完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 2017-02-21
    相关资源
    最近更新 更多