Hibernate内部运作

时间:2017-10-12 09:29:28

标签: java database hibernate jdbc

我正在使用Spring + Hibernate应用程序。我们已经为服务类方法应用了事务。我的问题

  1. hibernate可以使用单个连接/会话执行服务方法的所有db语句,还是使用多个连接?如果它使用多个连接,是否可以在任何运行时异常的情况下通过多个连接回滚db语句?

  2. 假设服务方法的业务逻辑执行需要的时间比removeAbandonedTimeout值多,那么在废弃的连接上如何进行提交/回滚?

  3. 如果我错在哪里,请纠正我。提前谢谢。

    更新 -

    如果查询比removeAbandonedTimeout花费更多时间,则抛出异常。假设我的服务方法有两个db调用,在这两个调用之间有一些业务逻辑(没有db调用)。在执行第一个查询之前,它创建数据库连接,假设第一个数据库调用花了1秒钟,然后业务逻辑执行需要60秒。如果此时连接被放弃(如果我们将removeAbandonedTimeout设置为60秒),要执行第二个db查询,它会创建另一个连接,对吗?如果第二个查询执行失败,则必须回滚第一个查询,因为它们共享同一个事务。废弃连接会怎么样?

2 个答案:

答案 0 :(得分:0)

  1. Hibernate will do what you told it to :

When integrating with spring, it will use spring managed transaction. Check where you are opening / closing tx (use of @Transactional on public method or directly using TransactionTemplate) : all hibernate queries inside will run in the same transaction.

  1. This is a question related to your connection pool (dbcp ?). Do not activate the removeAbandonedTimeout flag : removeAbandonedOnMaintenance : from documentation :

Setting one or both of these to true can recover db connections from poorly written applications which fail to close connections.

If you are using typical spring / hibernate coding pattern, you are not poorly writting your application (from a database resource point of view), so no need to activate this flag : let your long running thread keep it's transaction. If an operation is running so slow without running any db query (that it would have triggered dbcp cleanup), you have two options :

  • Don't keep the connection to the database : cut your transaction in two : one before the long running process, one after
  • If you need to keep the tx open (because you have database lock you do not want to lose for example), try to optimize the code in between using cpu sampling tool for example.

答案 1 :(得分:0)

Answers for your questions:

  1. With single connection we can execute all db statements of service.We cannot rollback db statements over multiple connections at a time.

  2. In general the removeAbandonedTimeout value should be set to the longest running query your applications might have.If the removeAbandonedTimeout exceeds and if removeAbandoned = true, the db connections can be recovered.