Java Spring事务边界和DB连接保持

Java Spring事务边界和DB连接保持,java,spring,hibernate,jpa,transactions,Java,Spring,Hibernate,Jpa,Transactions,我正在使用SpringBoot和HibernateoverJPA与tomcat连接池。您能帮助我理解spring在事务期间如何使用DB连接吗。例如,考虑下面的场景: 我们有2个连接的DB连接池 Spring启动一个事务,即用@Transactional注释修饰的调用方法 此方法执行数据库更新 调用外部服务 当从外部服务接收到响应时,它更新数据库并返回 Spring提交事务 假设外部服务(步骤4)需要1分钟才能完成,那么数据库池中有多少个数据库连接可用?。假设spring保持DB连接,直到事务完成

我正在使用SpringBoot和HibernateoverJPA与tomcat连接池。您能帮助我理解spring在事务期间如何使用DB连接吗。例如,考虑下面的场景:

  • 我们有2个连接的DB连接池
  • Spring启动一个事务,即用@Transactional注释修饰的调用方法
  • 此方法执行数据库更新
  • 调用外部服务
  • 当从外部服务接收到响应时,它更新数据库并返回
  • Spring提交事务
  • 假设外部服务(步骤4)需要1分钟才能完成,那么数据库池中有多少个数据库连接可用?。假设spring保持DB连接,直到事务完成,在此期间接收到的任何请求只有1个DB连接可用,如果我们接收到1个以上的请求,他们将不得不等待DB连接

    请确认我的理解,如果正确,请建议我如何在高交易量系统中处理这种情况


    谢谢

    您可以根据需要指定连接池的初始大小和最大大小(取决于应用程序的性能)

    比如说,

    <bean id="springDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
       <property name="url" value="jdbc:oracle:thin:@localhost:1521:SPRING_TEST" />
       <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
       <property name="username" value="root" />
       <property name="password" value="root" />
       <property name="removeAbandoned" value="true"/>
       <property name="initialSize" value="20" />
       <property name="maxActive" value="30" />
    </bean>
    
    
    

    当initialSize为20时,这将创建20个数据库连接,当maxActive为30时,如果需要,将最多创建30个数据库连接。您可以使用ApacheDBCP库提供的不同属性自定义数据库连接池。上面的示例是使用Oracle 11g数据库创建连接池,我使用的是Oracle.jdbc.driver.OracleDriver与ojdbc6.jar或ojdbc6_g.jar一起提供。首先,您的理解是正确的。请参阅有关的spring文档

    我猜您在事务中执行外部服务调用,因为您希望在出现异常时回滚数据库更改。或者换句话说,您希望db更新反映外部服务调用的状态

    如果是这样,则无法将其移出事务边界。在这种情况下,您应该增加连接池的大小,或者可以将长时间运行的事务委托给处理它们的专用服务器节点。这将使处理用户请求的“主”服务器节点远离长时间运行的事务


    您应该考虑数据的一致性。db更新必须与外部服务调用同步,这真的有必要吗?外部服务呼叫是否可以移出事务边界?

    答案中的链接为broken@RegularUser谢谢你的提示。我更新了链接。提取对@Transactional(传播=传播。不受支持)修饰的方法进行外部服务调用的逻辑能否解决事务长时间处于活动状态的问题?当调用此新方法时,当前事务将被挂起(释放连接和其他获取的资源),当此方法返回或抛出错误时,当前事务将再次恢复。因此,您仍然可以在事务上下文本身中使用这个新方法调用(或外部服务)返回的结果。