Spring爲事務管理提供了一致的編程模板,在高層次創建了統一的事務抽象。也就是說,無論選擇Spring JDBC、Hibernate 、JPA 仍是iBatis,Spring都讓咱們能夠用統一的編程模型進行事務管理。java
<context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"/> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource"/> ... <bean id="transactionManger" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFacotry-ref="entityManagerFactory"/>
3)Hibernatespring
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" p:dataSource-ref="dataSource" p:mappingResources="classpath:bbtForum.hbm.xml"> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.generate_statistics">true</prop> </props> </property> </bean>
<jee:jndi-lookup id="accountDs" jndi-name="java:comp/env/jdbc/account"/> <jee:jndi-lookup id="orderDs" jndi-name="java:comp/env/jdbc/account"/> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
package com.baobaotao.service; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import com.baobaotao.dao.ForumDao; import com.baobaotao.domain.Forum; public class ForumService1 { private ForumDao forumDao; //經過IoC注入 private TransactionTemplate template; public void addForum(final Forum forum) { template.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { //須要在事務環境中執行的代碼 forumDao.addForum(forum); } }); } public void setForumDao(ForumDao forumDao) { this.forumDao = forumDao; } public void setTemplate(TransactionTemplate template) { this.template = template; } }
package com.yyq.service; import com.yyq.domain.Forum; import com.yyq.domain.Topic; public interface BbtForum { void addTopic(Topic topic) throws Exception; void updateForum(Forum forum); Forum getForum(int forumId); int getForumNum(); }
BbtForumImpl實現類:sql
package com.yyq.service.impl; import com.yyq.dao.ForumDao; import com.yyq.dao.PostDao; import com.yyq.dao.TopicDao; import com.yyq.domain.Forum; import com.yyq.domain.Topic; import com.yyq.service.BbtForum; public class BbtForumImpl implements BbtForum { private ForumDao forumDao; private TopicDao topicDao; private PostDao postDao; public void addTopic(Topic topic) throws Exception { topicDao.addTopic(topic); // if(true) throw new PessimisticLockingFailureException("fail"); postDao.addPost(topic.getPost()); } public Forum getForum(int forumId) { return forumDao.getForum(forumId); } public void updateForum(Forum forum) { forumDao.updateForum(forum); } public int getForumNum() { return forumDao.getForumNum(); } public void setForumDao(ForumDao forumDao) { this.forumDao = forumDao; } public void setPostDao(PostDao postDao) { this.postDao = postDao; } public void setTopicDao(TopicDao topicDao) { this.topicDao = topicDao; } }
Dao和Datasource配置文件applicationContext-dao.xml:express
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"/> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"/> <bean id="abstracDao" abstract="true" p:jdbcTemplate-ref="jdbcTemplate"/> <bean id="forumDao" parent="abstracDao" class="com.yyq.dao.jdbc.ForumDaoImpl" /> <bean id="postDao" parent="abstracDao" class="com.yyq.dao.jdbc.PostDaoImpl"/> <bean id="topicDao" parent="abstracDao" class="com.yyq.dao.jdbc.TopicDaoImpl"/> </beans>
1)使用原始的TransactionProxyFactoryBean進行聲明式事務配置:apache
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!--導入Dao和DataSource的配置文件--> <import resource="applicationContext-dao.xml"/> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--須要實施事務加強的目標業務Bean--> <bean id="bbtForumTarget" class="com.yyq.service.impl.BbtForumImpl" p:forumDao-ref="forumDao" p:topicDao-ref="topicDao" p:postDao-ref="postDao"/> <!--使用事務代理工程類爲目標業務Bean提供事務加強--> <bean id="bbtForum" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" p:transactionManager-ref="txManager" p:target-ref="bbtForumTarget"> <property name="transactionAttributes"> <props> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> </beans>
測試方法:編程
import com.yyq.domain.Post; import com.yyq.domain.Topic; import com.yyq.service.BbtForum; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestBbtForumPfb { public static void main(String[] args) throws Throwable{ String configPath = "classpath:applicationContext-pfb.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); BbtForum bbtForum = ctx.getBean("bbtForum",BbtForum.class); System.out.println("begin........"); Topic topic = new Topic(); topic.setTopicTitle("Title -pfb"); Post post = new Post(); post.setPostText("post content -pfb"); topic.setPost(post); bbtForum.addTopic(topic); System.out.println("end........"); } }
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!--導入Dao和DataSource的配置文件--> <import resource="classpath:applicationContext-dao.xml"/> <!--聲明事務管理器--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"/> <!--再也不須要爲了事務AOP加強的實施而更名換姓--> <bean id="bbtForum" class="com.yyq.service.impl.BbtForumImpl" p:forumDao-ref="forumDao" p:topicDao-ref="topicDao" p:postDao-ref="postDao"/> <!--使用強大的切點表達式語言輕鬆定義目標方法--> <aop:config> <!--經過aop定義事務加強切面--> <aop:pointcut id="serviceMethod" expression="execution(* com.yyq.service.*Forum.*(..))"/> <!--引用事務加強--> <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/> </aop:config> <!--事務加強--> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <!--事務屬性定義--> <tx:method name="get*" read-only="false"/> <tx:method name="add*" rollback-for="PessimisticLockingFailureException"/> <tx:method name="update*"/> </tx:attributes> </tx:advice> </beans>
測試方法:session
import com.yyq.domain.Post; import com.yyq.domain.Topic; import com.yyq.service.BbtForum; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestBbtForumTx { public static void main(String[] args) throws Throwable{ String configPath = "classpath:applicationContext-tx.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); BbtForum bbtForum = ctx.getBean(BbtForum.class); System.out.println("begin........"); Topic topic = new Topic(); topic.setTopicTitle("Title Tx-"); Post post = new Post(); post.setPostText("post content -Tx"); topic.setPost(post); bbtForum.addTopic(topic); System.out.println("end........"); } }
@Transactional public class BbtForumImpl implements BbtForum { private ForumDao forumDao; private TopicDao topicDao; private PostDao postDao; public void addTopic(Topic topic) throws Exception { topicDao.addTopic(topic); //if(true) throw new PessimisticLockingFailureException("fail"); postDao.addPost(topic.getPost()); } public Forum getForum(int forumId) { return forumDao.getForum(forumId); } public void updateForum(Forum forum) { forumDao.updateForum(forum); } ....
applicationContext-anno.xml:使事務註解生效app
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <import resource="classpath:applicationContext-dao.xml"/> <!--因爲該Bean實現類標註了@Transaction,因此將會被註解驅動自動織入事務--> <bean id="bbtForum" class="com.yyq.service.impl.BbtForumImpl" p:forumDao-ref="forumDao" p:topicDao-ref="topicDao" p:postDao-ref="postDao"/> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"/> <!--對標註@Transaction註解的Bean進行加工處理,以織入事務管理切面--> <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/> </beans>