Spring事务边界和DB连接保持

时间:2014-11-05 07:39:31

标签: java spring hibernate jpa transactions

我正在使用spring boot并使用tomcat连接池在jpa上休眠。能帮我理解spring在事务处理中如何使用数据库连接。例如,请考虑以下情况:

  1. 我们有2个连接的数据库连接池。
  2. Spring启动一个事务,即用@Transactional注释装饰的调用方法。
  3. 此方法执行数据库更新
  4. 调用外部服务
  5. 当收到外部服务的响应时,它会更新数据库并返回。
  6. Spring提交交易
  7. 假设外部服务(步骤4)需要1分钟才能完成,数据库池中可用的数据库连接数量是多少?假设spring保持DB连接,直到事务完成,在此期间收到的任何请求只有1个DB连接可用,如果我们收到多个请求,则必须等待数据库连接。

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

    由于

2 个答案:

答案 0 :(得分:8)

首先你的理解是正确的。请参阅有关declarative transaction management的弹簧文档。

enter image description here

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

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

你应该考虑数据的一致性。是否必须将db更新与外部服务调用同步?外部服务调用是否可以移出事务边界?

答案 1 :(得分:3)

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

例如,

<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>

这将创建20个数据库连接,因为initialSize为20并且如果需要,则最多为30个数据库连接,因为maxActive为30.您可以使用Apache DBCP库提供的不同属性来自定义数据库连接池。以上示例是使用Oracle 11g数据库创建连接池,我正在使用oracle.jdbc.driver.OracleDriver附带ojdbc6.jar或ojdbc6_g.jar