<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>-Flyぁ梦- &#187; 数据库</title>
	<atom:link href="http://blog.11034.org/tag/%e6%95%b0%e6%8d%ae%e5%ba%93/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.11034.org</link>
	<description></description>
	<lastBuildDate>Sun, 22 Jun 2025 08:59:05 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.38</generator>
	<item>
		<title>Tomcat监听shutdown释放数据库连接池</title>
		<link>http://blog.11034.org/2016-06/tomcat_shutdown.html</link>
		<comments>http://blog.11034.org/2016-06/tomcat_shutdown.html#comments</comments>
		<pubDate>Wed, 08 Jun 2016 12:41:47 +0000</pubDate>
		<dc:creator><![CDATA[-Flyぁ梦-]]></dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Tomcat]]></category>
		<category><![CDATA[数据库]]></category>
		<category><![CDATA[进程]]></category>

		<guid isPermaLink="false">http://blog.11034.org/?p=2836</guid>
		<description><![CDATA[开发时因为更新代码，频繁重启Tomcat，遇到一个问题：在执行shutdown脚本后，Tomcat进程没有关闭 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>开发时因为更新代码，频繁重启Tomcat，遇到一个问题：在执行shutdown脚本后，Tomcat进程没有关闭依然存在（但是HTTP服务已经停止），需要手动执行kill命令才行。查了一些资料结合经验，应该是所使用的数据库连接池中的连接没有被释放的问题引起的。所以解决的办法，就是想办法做一个Tomcat的shutdown的事件监听，然后手动释放数据库连接即可。<span id="more-2836"></span></p>
<h2>Tomcat的shutdown的事件监听</h2>
<p>很简单，实现一个ServletContextListener的实例，并注册到web.xml中即可。</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ShutdownListener <span style="color: #000000; font-weight: bold;">implements</span> ServletContextListener  <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> Logger logger <span style="color: #339933;">=</span> Logger.<span style="color: #006633;">getLogger</span><span style="color: #009900;">&#40;</span>ShutdownListener.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	@Override
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> contextDestroyed<span style="color: #009900;">&#40;</span>ServletContextEvent arg0<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		logger.<span style="color: #006633;">info</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;contextDestroyed&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		logger.<span style="color: #006633;">info</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;DBPool shutdown start...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
			DBPool.<span style="color: #006633;">clear</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			DBPool.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Throwable</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			logger.<span style="color: #006633;">fatal</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&quot;</span>, e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		logger.<span style="color: #006633;">info</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;DBPool shutdown done&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	@Override
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> contextInitialized<span style="color: #009900;">&#40;</span>ServletContextEvent arg0<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		logger.<span style="color: #006633;">info</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;contextInitialized&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;listener<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;listener-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>xxx.xxx.xxx.ShutdownListener<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/listener-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/listener<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<h2>数据库连接池的关闭和释放</h2>
<p>代码中没有使用复杂的数据库连接池，是用<code class="markdown_inline_code">org.apache.commons.pool.impl.GenericObjectPool</code>和<code class="markdown_inline_code">org.apache.commons.pool.BasePoolableObjectFactory</code>组合实现的。</p>
<p>在ServletContextListener的contextDestroyed方法中</p>
<ol>
<li>执行GenericObjectPool.clear()，是将池内缓存的对象全部销毁</li>
<li>执行GenericObjectPool.close()，关闭对象池，不再支持borrowObject()，但依然支持returnObject()方法且return后将对象立即销毁</li>
</ol>
<p>做完这两步，执行Tomcat的shutdown脚本后，Tomcat进程过几秒就会自动关闭了。</p>
<h4  class="related_post_title">看看 Tomcat , 数据库 , 进程</h4><ul class="related_post"><li>2016-06-06 -- <a target="_blank" href="http://blog.11034.org/2016-06/tomcat_https.html" title="Tomcat启用https服务">Tomcat启用https服务</a></li><li>2015-08-28 -- <a target="_blank" href="http://blog.11034.org/2015-08/tomcat_linux.html" title="Linux下搭建Tomcat环境">Linux下搭建Tomcat环境</a></li><li>2015-01-07 -- <a target="_blank" href="http://blog.11034.org/2015-01/prevent_db_duplicate.html" title="防止数据库数据重复的几种方法">防止数据库数据重复的几种方法</a></li><li>2013-05-20 -- <a target="_blank" href="http://blog.11034.org/2013-05/coyote.html" title="Tomcat的Connector：Coyote">Tomcat的Connector：Coyote</a></li><li>2013-05-19 -- <a target="_blank" href="http://blog.11034.org/2013-05/tomcat6.html" title="Tomcat6源码学习">Tomcat6源码学习</a></li></ul><h4 class="related_post_title">看看 Java </h4><ul class="related_post"><li>2016-09-09 -- <a target="_blank" href="http://blog.11034.org/2016-09/64bits_linux_arena_memory.html" title="64位Linux下Java进程堆外内存迷之64M问题">64位Linux下Java进程堆外内存迷之64M问题</a></li><li>2016-08-18 -- <a target="_blank" href="http://blog.11034.org/2016-08/java_concurrency_in_practice.html" title="读java concurrency in practice">读java concurrency in practice</a></li><li>2016-08-05 -- <a target="_blank" href="http://blog.11034.org/2016-08/thread_stop.html" title="线程清理">线程清理</a></li><li>2016-06-21 -- <a target="_blank" href="http://blog.11034.org/2016-06/futuretask.html" title="FutureTask简单分析和用法">FutureTask简单分析和用法</a></li><li>2016-06-21 -- <a target="_blank" href="http://blog.11034.org/2016-06/semaphore.html" title="Semaphore简单分析">Semaphore简单分析</a></li>]]></content:encoded>
			<wfw:commentRss>http://blog.11034.org/2016-06/tomcat_shutdown.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>防止数据库数据重复的几种方法</title>
		<link>http://blog.11034.org/2015-01/prevent_db_duplicate.html</link>
		<comments>http://blog.11034.org/2015-01/prevent_db_duplicate.html#comments</comments>
		<pubDate>Wed, 07 Jan 2015 09:22:49 +0000</pubDate>
		<dc:creator><![CDATA[-Flyぁ梦-]]></dc:creator>
				<category><![CDATA[Life in Coding]]></category>
		<category><![CDATA[同步]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[数据库]]></category>

		<guid isPermaLink="false">http://blog.11034.org/?p=2374</guid>
		<description><![CDATA[在某些数据库表中，比如记录的是一些关联关系，比如某个人关注了另外一个人，person_id和target_id [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>在某些数据库表中，比如记录的是一些关联关系，比如某个人关注了另外一个人，person_id和target_id，这种数据表的数据如果出现了重复，可能会引起程序上其他地方的诡异bug，要尽量保持数据的唯一性。这种数据重复，要不就是插入数据时根本没有做存在检查，或者是可能由二次提交产生的比较麻烦的并发情况。</p>
<pre class="markdown_pre"><code>1. 代码层做同步控制，利用锁机制
2. 在数据查重时利用数据库事务 + SQL层加入排他锁，select * from xx where ... lock for update
3. 数据库层Unique检查，建表时加入unique的索引</code></pre>
<p>前两个方法在代码层面，比较容易控制，第三种方法最彻底但是出现冲突时候会报异常。</p>
<p>不过如果在高并发的情况下，使用第三种方式然后主动捕获异常，也是很不错的甚至是最好的。</p>
<h4  class="related_post_title">看看 同步 , 并发 , 数据库</h4><ul class="related_post"><li>2016-08-18 -- <a target="_blank" href="http://blog.11034.org/2016-08/java_concurrency_in_practice.html" title="读java concurrency in practice">读java concurrency in practice</a></li><li>2016-06-16 -- <a target="_blank" href="http://blog.11034.org/2016-06/reentrantreadwritelock.html" title="ReentrantReadWriteLock简单分析">ReentrantReadWriteLock简单分析</a></li><li>2016-06-13 -- <a target="_blank" href="http://blog.11034.org/2016-06/reentrantlock.html" title="可重入锁、ReentrantLock、AQS、Condition">可重入锁、ReentrantLock、AQS、Condition</a></li><li>2016-06-08 -- <a target="_blank" href="http://blog.11034.org/2016-06/tomcat_shutdown.html" title="Tomcat监听shutdown释放数据库连接池">Tomcat监听shutdown释放数据库连接池</a></li></ul><h4 class="related_post_title">看看 Life in Coding </h4><ul class="related_post"><li>2016-09-09 -- <a target="_blank" href="http://blog.11034.org/2016-09/jabber_and_xmpp.html" title="jabber和XMPP简述原理">jabber和XMPP简述原理</a></li><li>2014-10-25 -- <a target="_blank" href="http://blog.11034.org/2014-10/linux_timeout.html" title="linux的timeout处理wkhtmltopdf进程超时">linux的timeout处理wkhtmltopdf进程超时</a></li><li>2014-09-10 -- <a target="_blank" href="http://blog.11034.org/2014-09/dotnet_csharp_excel.html" title="记C#和Excel开发">记C#和Excel开发</a></li><li>2011-06-11 -- <a target="_blank" href="http://blog.11034.org/2011-06/google_doodle_guitar.html" title="2011-6-9 Google Doodle之电子琴">2011-6-9 Google Doodle之电子琴</a></li><li>2011-03-10 -- <a target="_blank" href="http://blog.11034.org/2011-03/learning_cs.html" title="学计算机的尼玛伤不起啊！！！！！！">学计算机的尼玛伤不起啊！！！！！！</a></li>]]></content:encoded>
			<wfw:commentRss>http://blog.11034.org/2015-01/prevent_db_duplicate.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
