Java tomcat重新部署时的JDBC事务行为

Java tomcat重新部署时的JDBC事务行为,java,tomcat,jdbc,connection-pooling,Java,Tomcat,Jdbc,Connection Pooling,当我有许多活动的JDBC事务并且重新部署命中web应用程序时会发生什么情况?我搜索了Tomcat文档,但没有找到任何相关的内容 例如:30个客户拥有一个购物车,购物车中有商品,他们同时保存订单,因此启动交易并触发重新部署 会发生什么?所有项目是否正确保存?或者在重新部署时,所有活动事务都将被丢弃?或者Tomcat等待重新部署命令直到提交所有事务 我正在使用Tomcat JDBC池要记住的关键点是连接池在哪里实例化 如果在上下文级别定义连接池,则在创建上下文时会创建连接池,并且应该随上下文一起销毁

当我有许多活动的JDBC事务并且重新部署命中web应用程序时会发生什么情况?我搜索了Tomcat文档,但没有找到任何相关的内容

例如:30个客户拥有一个购物车,购物车中有商品,他们同时保存订单,因此启动交易并触发重新部署 会发生什么?所有项目是否正确保存?或者在重新部署时,所有活动事务都将被丢弃?或者Tomcat等待重新部署命令直到提交所有事务


我正在使用Tomcat JDBC池

要记住的关键点是连接池在哪里实例化

如果在
上下文
级别定义连接池,则在创建上下文时会创建连接池,并且应该随上下文一起销毁连接池

在Tomcat中重新部署应用程序需要关闭当前上下文,然后启动替换上下文。因此,在这种情况下,我希望行为将由每个事务的
autoCommit
的值或有效值决定。如果
true
,则关闭资源应提交事务。如果
false
,则与任何
InterruptedException
一样,异常处理路径应该触发回滚,或者在最坏的情况下,连接关闭应该回滚事务

您真正想要检查的是Tomcat是如何关闭应用程序的。我没有详细研究实际的代码,但我的理解是,首先它停止向“旧上下文”发送请求。然后,一旦所有挂起的响应完成,就会调用ServletContextListeners通知关闭,一旦它们及其过滤器和Servlet对应项完成,就会有效地关闭上下文并清理资源。使事情复杂化的是,IIRC是Tomcat不会永远等待响应完成,并且可能会开始中断处理程序的运行,或者只是简单地切换到新上下文,而不等待旧上下文或完成中断

我不记得哪个容器(jetty/tomcat)支持启动新上下文,然后在新上下文准备好提供零停机切换时才切换请求处理。。。关键问题是,您需要一个持久会话存储和一个可以在集群上安全运行的应用程序,以便能够使用这种部署模式


简而言之,您的应用程序将在新上下文启动之前正常关闭,因此,我希望事务能够完成或生成一个
中断异常
,此时您的
尝试…最后
块应该启动

同样,为了实现高可用性,在不同的服务器节点上(在LB或反向代理之后)至少运行两个Tomcat是有用的因此,应用程序更新和操作系统补丁程序时,用户不会遇到停机。通过这种方式,您还可以在卸载上下文之前有一个“宽限期”:让LB将所有通信定向到另一个Tomcat,等待处理挂起的请求,然后重新部署或关闭。会话复制是使其真正工作所必需的。@Stephen Connolly我在server.xml中声明了我的连接池,这是否意味着我的连接池即使在对使用它的应用程序触发重新部署时也会运行?如果您在服务器上下文中声明了连接池,然后,仅当服务器上下文关闭时,池本身才会关闭。这是有意义的,因为服务器中的其他应用程序也可能使用相同的池(这就是为什么您首先在服务器级别设置池)。在这种情况下,在某个时间点:如果webapp关闭时间过长,事务将超时,并因此回滚;或者webapp将使用响应和提交来完成事务。@Stephen Connolly,请纠正我:即使在重新部署应用程序时在服务器上下文中声明了连接池,并且有事务正在运行,这些事务的结果也不可预测—提交确定或回滚,无法预测这种行为。在某些情况下,如果应用程序关闭时间过长,tomcat将放弃等待,尝试中断或以其他方式迫使不合作的应用程序出现问题。在这些情况下,行为将是回滚任何悬而未决的交易。一个写得好的应用程序永远不会达到那种状态。这样想,tomcat停止给旧应用程序新的工作,等待旧的工作完成。。。在某个时刻,它要么不得不放弃,要么迫使管理员重新启动Tomcat,这会产生同样的问题