p.s 这里很多hibernate和spring配置文件是隐藏的,只有一些重要的文件显示,如果你想看全部文件,请在文章的结尾下载完整的项目代码。
create table `h3`.`product` ( `product_id` bigint(20) unsigned not null auto_increment, `product_code` varchar(20) not null, `product_desc` varchar(255) not null, primary key (`product_id`) using btree ) engine=innodb auto_increment=1 default charset=utf8; create table `h3`.`product_qoh` ( `qoh_id` bigint(20) unsigned not null auto_increment, `product_id` bigint(20) unsigned not null, `qty` int(10) unsigned not null, primary key (`qoh_id`), key `fk_product_qoh_product_id` (`product_id`), constraint `fk_product_qoh_product_id` foreign key (`product_id`) references `product` (`product_id`) ) engine=innodb auto_increment=1 default charset=utf8;
package com.h3.product.bo.impl; import com.h3.product.bo.productbo; import com.h3.product.bo.productqohbo; import com.h3.product.dao.productdao; import com.h3.product.model.product; import com.h3.product.model.productqoh; public class productboimpl implements productbo{ productdao productdao; productqohbo productqohbo; public void setproductdao(productdao productdao) { this.productdao = productdao; } public void setproductqohbo(productqohbo productqohbo) { this.productqohbo = productqohbo; } //this method need to be transactional public void save(product product, int qoh){ productdao.save(product); system.out.println("product inserted"); productqoh productqoh = new productqoh(); productqoh.setproductid(product.getproductid()); productqoh.setqty(qoh); productqohbo.save(productqoh); system.out.println("productqoh inserted"); } }
<!-- product business object --> <bean id="productbo" class="com.h3.product.bo.impl.productboimpl" > <property name="productdao" ref="productdao" /> <property name="productqohbo" ref="productqohbo" /> </bean> <!-- product data access object --> <bean id="productdao" class="com.h3.product.dao.impl.productdaoimpl" > <property name="sessionfactory" ref="sessionfactory"></property> </bean>
运行它
product product = new product(); product.setproductcode("abc"); product.setproductdesc("this is product abc"); productbo productbo = (productbo)appcontext.getbean("productbo"); productbo.save(product, 100);
假设save() 不具有事务功能,如果异常抛出由productqohbo.save(),钭只插入一条记录到“product”表,没有记录将被插入到“productqoh'表。这是一个严重的问题,在数据库中打破数据一致性。
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="transactioninterceptor" class="org.springframework.transaction.interceptor.transactioninterceptor"> <property name="transactionmanager" ref="transactionmanager" /> <property name="transactionattributes"> <props> <prop key="save">propagation_required</prop> </props> </property> </bean> <bean id="transactionmanager" class="org.springframework.orm.hibernate3.hibernatetransactionmanager"> <property name="datasource" ref="datasource" /> <property name="sessionfactory" ref="sessionfactory" /> </bean> </beans>
在事务拦截器,必须定义的事务的属性“传播行为”应使用。这意味着,如果一个事务“productboimpl.save()方法被调用另外的”productqohbo.save()'方法,事务应该怎么传播?它能继续在现有的事务中运行?或者为自己开始一个新的事务。
在hibernate事务,需要使用 hibernatetransactionmanager 。 如果只对付纯jdbc,usedatasourcetransactionmanager; 而如果是 jta,需要使用 jtatransactionmanager 。
<!-- product business object --> <bean id="productbo" class="com.h3.product.bo.impl.productboimpl" > <property name="productdao" ref="productdao" /> <property name="productqohbo" ref="productqohbo" /> </bean> <!-- product data access object --> <bean id="productdao" class="com.h3.product.dao.impl.productdaoimpl" > <property name="sessionfactory" ref="sessionfactory"></property> </bean> <bean id="productboproxy" class="org.springframework.aop.framework.proxyfactorybean"> <property name="target" ref="productbo" /> <property name="interceptornames"> <list> <value>transactioninterceptor</value> </list> </property> </bean>
运行它
product product = new product(); product.setproductcode("abc"); product.setproductdesc("this is product abc"); productbo productbo = (productbo)appcontext.getbean("productboproxy"); productbo.save(product, 100);