<?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>机械境-信永软件工程师培训学校 &#187; spring</title>
	<atom:link href="http://code.oseschool.com/index.php/archives/tag/spring/feed" rel="self" type="application/rss+xml" />
	<link>http://code.oseschool.com</link>
	<description>世界：男人、女人、程序员</description>
	<lastBuildDate>Sun, 07 Mar 2010 02:43:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SSH开发心得</title>
		<link>http://code.oseschool.com/index.php/archives/42</link>
		<comments>http://code.oseschool.com/index.php/archives/42#comments</comments>
		<pubDate>Mon, 24 Aug 2009 13:53:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://code.oseschool.com/?p=42</guid>
		<description><![CDATA[前段时间开发一个J2EE的Web项目，使用SSH（Struts+Spring+hibernate）框架。开发过程中遇到一个相当郁闷的问题,困扰了我好几天。这里我跟大家分享一下。
问题是这样的：我用Spring的声明式事务管理来管理事务，当出现异常时能回滚事务。于是我做了一个测试，在一个方法里，我先添加了一条数据，然后再删除一条数据，在删除数据的时候我让它强行抛出异常，这时刚添加的那条数据应该回滚掉，可是我查看了一下数据库，发现数据已经插入，根本没有回滚，这是怎么回事呢？我的第一个反应就是Spring配置文件可能出问题了。
以下是我的Spring的事务管理的配置方式：

	&#60;bean id=&#34;transactionManager&#34; class=&#34;org.springframework.orm.hibernate3.HibernateTransactionManager&#34;&#62;
	&#60;propertyname=&#34;sessionFactory&#34;ref=&#34;sessionFactory&#34;/&#62;
	&#60;/bean&#62;
&#160;
	&#60;bean id=&#34;transactionInterceptor&#34; class=&#34;org.springframework.transaction.interceptor.TransactionInterceptor&#34;&#62;
	&#60;!--事务拦截器bean需要依赖注入一个事务管理器--&#62;
	&#60;property name=&#34;transactionManager&#34;ref=&#34;transactionManager&#34;/&#62;
	&#60;property name=&#34;transactionAttributes&#34;&#62;
	&#60;!--下面定义事务传播属性--&#62;
	&#60;props&#62;
	&#60;prop key=&#34;get*&#34;&#62;PROPAGATION_REQUIRED,readOnly&#60;/prop&#62;
	&#60;prop key=&#34;*&#34;&#62;PROPAGATION_REQUIRED,-Exception&#60;/prop&#62;
	&#60;/props&#62;
	&#60;/property&#62;
	&#60;/bean&#62;
		&#60;!--定义BeanNameAutoProxyCreator--&#62;
		&#60;bean
		class=&#34;org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator&#34;&#62;
			&#60;!--指定对满足哪些beanname的bean自动生成业务代理--&#62;
			&#60;property name=&#34;beanNames&#34;&#62;
				&#60;!--下面是所有需要自动创建事务代理的bean--&#62;
				&#60;list&#62;
					&#60;value&#62;*Bo&#60;/value&#62;
				&#60;/list&#62;
				&#60;!--此处可增加其他需要自动创建事务代理的bean--&#62;
			&#60;/property&#62;
			&#60;!--下面定义BeanNameAutoProxyCreator所需的事务拦截器--&#62;
			&#60;property name=&#34;interceptorNames&#34;&#62;
				&#60;list&#62;
					&#60;!--此处可增加其他新的Interceptor--&#62;
					&#60;value&#62;transactionInterceptor&#60;/value&#62;
				&#60;/list&#62;
			&#60;/property&#62;
		&#60;/bean&#62;

带着这个问题，我到网络上查了很多关于Spring配置事务的资料，也做了很多次修改，但问题仍然存在。我开始怀疑难道是Spring配置方式根本就是正确的。那这样的话问题到底出在哪里呢？为什么抛出异常后事务没有回滚呢？
快接近崩溃边缘的我还是硬着头皮继续在网络上求教，突然在一篇文章里看到这样一句话“Mysql表的MyISAM类型不支持事务处理，InnoDB类型提供事务支持”。我马上查了一下数据库的表类型，发现我的表就是MyISAM类型的，太兴奋了,难道就这样搞定了?于是我马上将表类型改成InnoDB，重启测试，问题解决。兴奋之余总结一下:原因就是我一直以为是Spring配置文件出问题了，却一直忽略了其他的情况。最后，将Mysql这两种表类型的详细对比跟大家分享一下。
InnoDB和MyISAM是MySQL最常用的表类型，各有各的优缺点，选用哪个视具体应用场景而定。
MyIASM:基于传统的IASM类型,ISAM是Indexed Sequential Access Method(有索引的顺序访问方法)的缩写,IASM是存储记录和文件的标准方法。与其他存储引擎比较,MyISAM具有检查和修复表的大多数工具。MyISAM表可以被压缩,而且它们支持全文搜索。它们不是事务安全的,而且也不支持外键。如果事物回滚将造成不完全回滚，不具有原子性。如果执行大量的SELECT，MyISAM是更好的选择。MyISAM对IASM有如下扩展：
二进制层次的可移植性。
NULL列索引。
对变长行比ISAM表有更少的碎片。
支持大文件。
更好的索引压缩。
更好的键码统计分布。
更好和更快的auto_increment处理。
InnoDB:它是事务安全的,与BDB类型具有相同的特性。它们支持外键。InnoDB表速度很快,具有比BDB还丰富的特性,因此如果需要一个事务安全的存储引擎,建议使用它。如果你的数据执行大量的INSERT或UPDATE,出于性能与事务方面的考虑，应该使用InnoDB类型的表。
以下是InnoDB与MyISAM细节和具体实现的差别：
InnoDB有它自己的缓冲池，能缓冲数据和索引，InnoDB把数据和索引存放在表空间里面，可能包含好几个文件，在MyISAM中，表被存放在单独的文件中，InnoDB表的大小只受限于操作系统文件的大小，一般为2GB。InnoDB不支持FULLTEXT类型的索引。
InnoDB支持行锁，提供和Oracle一样的一致性的不加锁读取，能增加并发读的用户数量并提高性能，不会增加锁的数量。另外，InnoDB表的行锁也不是绝对的，如果在执行一个SQL语句时MySQL不能确定要扫描的范围，InnoDB表同样会锁全表，例如update table set num=1 where name like“%aaa%”。
InnoDB中不保存表的具体行数，也就是说，执行selectcount(*)fromtable时，InnoDB要扫描一遍整个表来计算有多少行，但是MyISAM只要简单的读出保存好的行数即可。要注意的是，当count(*)语句包含where条件时，两种表的操作是一样的。
对于AUTO_INCREMENT类型的字段，InnoDB中必须包含只有该字段的索引，但是在MyISAM表中，可以和其他字段一起建立联合索引。
DELETE FROM table时，InnoDB不会重新建立表，而是一行一行的删除。
LOAD TABLE FROM MASTER操作对InnoDB是不起作用的，解决方法是首先把InnoDB表改成MyISAM表，导入数据后再改成InnoDB表，但是对于使用的额外的InnoDB特性（例如外键）的表不适用。
任何一种表类型都不是万能的，只能针对具体的应用场景来选择合适的表类型，这样才能最大限度地发挥MySQL的性能。
]]></description>
			<content:encoded><![CDATA[<p>前段时间开发一个J2EE的Web项目，使用SSH（Struts+Spring+hibernate）框架。开发过程中遇到一个相当郁闷的问题,困扰了我好几天。这里我跟大家分享一下。</p>
<p>问题是这样的：我用Spring的声明式事务管理来管理事务，当出现异常时能回滚事务。于是我做了一个测试，在一个方法里，我先添加了一条数据，然后再删除一条数据，在删除数据的时候我让它强行抛出异常，这时刚添加的那条数据应该回滚掉，可是我查看了一下数据库，发现数据已经插入，根本没有回滚，这是怎么回事呢？我的第一个反应就是Spring配置文件可能出问题了。</p>
<p>以下是我的Spring的事务管理的配置方式：</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bean</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;transactionManager&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;org.springframework.orm.hibernate3.HibernateTransactionManager&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;">&lt;<span style="color: #000066;">propertyname</span>=<span style="color: #ff0000;">&quot;sessionFactory&quot;</span><span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;sessionFactory&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/bean<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bean</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;transactionInterceptor&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;org.springframework.transaction.interceptor.TransactionInterceptor&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #808080; font-style: italic;">&lt;!--事务拦截器bean需要依赖注入一个事务管理器--&gt;</span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;transactionManager&quot;</span><span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;transactionManager&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;transactionAttributes&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #808080; font-style: italic;">&lt;!--下面定义事务传播属性--&gt;</span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;props<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;prop</span> <span style="color: #000066;">key</span>=<span style="color: #ff0000;">&quot;get*&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>PROPAGATION_REQUIRED,readOnly<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/prop<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;prop</span> <span style="color: #000066;">key</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>PROPAGATION_REQUIRED,-Exception<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/prop<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/props<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/bean<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #808080; font-style: italic;">&lt;!--定义BeanNameAutoProxyCreator--&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bean</span></span>
<span style="color: #009900;">		<span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #808080; font-style: italic;">&lt;!--指定对满足哪些beanname的bean自动生成业务代理--&gt;</span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;beanNames&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
				<span style="color: #808080; font-style: italic;">&lt;!--下面是所有需要自动创建事务代理的bean--&gt;</span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;list<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
					<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>*Bo<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/list<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
				<span style="color: #808080; font-style: italic;">&lt;!--此处可增加其他需要自动创建事务代理的bean--&gt;</span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #808080; font-style: italic;">&lt;!--下面定义BeanNameAutoProxyCreator所需的事务拦截器--&gt;</span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;interceptorNames&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;list<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
					<span style="color: #808080; font-style: italic;">&lt;!--此处可增加其他新的Interceptor--&gt;</span>
					<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>transactionInterceptor<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/list<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/bean<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>带着这个问题，我到网络上查了很多关于Spring配置事务的资料，也做了很多次修改，但问题仍然存在。我开始怀疑难道是Spring配置方式根本就是正确的。那这样的话问题到底出在哪里呢？为什么抛出异常后事务没有回滚呢？</p>
<p>快接近崩溃边缘的我还是硬着头皮继续在网络上求教，突然在一篇文章里看到这样一句话“Mysql表的MyISAM类型不支持事务处理，InnoDB类型提供事务支持”。我马上查了一下数据库的表类型，发现我的表就是MyISAM类型的，太兴奋了,难道就这样搞定了?于是我马上将表类型改成InnoDB，重启测试，问题解决。兴奋之余总结一下:原因就是我一直以为是Spring配置文件出问题了，却一直忽略了其他的情况。最后，将Mysql这两种表类型的详细对比跟大家分享一下。</p>
<p>InnoDB和MyISAM是MySQL最常用的表类型，各有各的优缺点，选用哪个视具体应用场景而定。</p>
<p>MyIASM:基于传统的IASM类型,ISAM是Indexed Sequential Access Method(有索引的顺序访问方法)的缩写,IASM是存储记录和文件的标准方法。与其他存储引擎比较,MyISAM具有检查和修复表的大多数工具。MyISAM表可以被压缩,而且它们支持全文搜索。它们不是事务安全的,而且也不支持外键。如果事物回滚将造成不完全回滚，不具有原子性。如果执行大量的SELECT，MyISAM是更好的选择。MyISAM对IASM有如下扩展：</p>
<p>二进制层次的可移植性。</p>
<p>NULL列索引。</p>
<p>对变长行比ISAM表有更少的碎片。</p>
<p>支持大文件。</p>
<p>更好的索引压缩。</p>
<p>更好的键码统计分布。</p>
<p>更好和更快的auto_increment处理。</p>
<p>InnoDB:它是事务安全的,与BDB类型具有相同的特性。它们支持外键。InnoDB表速度很快,具有比BDB还丰富的特性,因此如果需要一个事务安全的存储引擎,建议使用它。如果你的数据执行大量的INSERT或UPDATE,出于性能与事务方面的考虑，应该使用InnoDB类型的表。</p>
<p>以下是InnoDB与MyISAM细节和具体实现的差别：</p>
<p>InnoDB有它自己的缓冲池，能缓冲数据和索引，InnoDB把数据和索引存放在表空间里面，可能包含好几个文件，在MyISAM中，表被存放在单独的文件中，InnoDB表的大小只受限于操作系统文件的大小，一般为2GB。InnoDB不支持FULLTEXT类型的索引。</p>
<p>InnoDB支持行锁，提供和Oracle一样的一致性的不加锁读取，能增加并发读的用户数量并提高性能，不会增加锁的数量。另外，InnoDB表的行锁也不是绝对的，如果在执行一个SQL语句时MySQL不能确定要扫描的范围，InnoDB表同样会锁全表，例如update table set num=1 where name like“%aaa%”。</p>
<p>InnoDB中不保存表的具体行数，也就是说，执行selectcount(*)fromtable时，InnoDB要扫描一遍整个表来计算有多少行，但是MyISAM只要简单的读出保存好的行数即可。要注意的是，当count(*)语句包含where条件时，两种表的操作是一样的。</p>
<p>对于AUTO_INCREMENT类型的字段，InnoDB中必须包含只有该字段的索引，但是在MyISAM表中，可以和其他字段一起建立联合索引。</p>
<p>DELETE FROM table时，InnoDB不会重新建立表，而是一行一行的删除。</p>
<p>LOAD TABLE FROM MASTER操作对InnoDB是不起作用的，解决方法是首先把InnoDB表改成MyISAM表，导入数据后再改成InnoDB表，但是对于使用的额外的InnoDB特性（例如外键）的表不适用。</p>
<p>任何一种表类型都不是万能的，只能针对具体的应用场景来选择合适的表类型，这样才能最大限度地发挥MySQL的性能。</p>
]]></content:encoded>
			<wfw:commentRss>http://code.oseschool.com/index.php/archives/42/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

