hibernate spring 事务

 

在我们的项目中我们可以使用spring的事务机制来处理,以此来节省工作量,一下就例子来讨论下:

实例:

采用spring2.x版本:hibenate3.x

首先:

看sessionfactory的配置,我们使用hibenate的sessionfactory配置:

<?xml version="1.0" encoding="UTF-8"?> <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.0.xsd" default-autowire="byName" default-lazy-init="true"> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">----//在此由于我使用的是annoation形式的po 如果配置其他将不能持久化 <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> </bean>></beans>

 

 

 
  

 

 当然也可以使用spring的datasource来配置,也就是使用:org.springframework.jdbc.datasource.DriverManagerDataSource,自我感觉这样分开比较好

 hibernate.cfg.xml:

<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration> <session-factory> <property name="connection.url"> jdbc:mysql://localhost:3306/hbman </property> <property name="connection.username">root</property> <property name="connection.password">root</property> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="hibernate.show_sql">true</property> <property name="hbm2ddl.auto">update</property> <property name="cache.provider_class"> org.hibernate.cache.EhCacheProvider </property> <property name="cache.use_second_level_cache">false</property> <property name="cache.use_query_cache">false</property> <property name="connection.isolation">2</property> <mapping class="com.po.A" /> </session-factory> </hibernate-configuration>

 

 

 
  

 

 

 我们的po类class A(使用hibenate anoation)

 

package com.po; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Version; @Entity public class A { private int id; private int anum; private String aname; private int version; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) public int getId() { return id; } public void setId(int id) { this.id = id; } @Version public int getVersion() { return version; } public void setVersion(int version) { this.version = version; } ....get set.. }

 

 

 
  

 

 dao:

 

public class Dao extends HibernateDaoSupport { public Serializable save(Object entity){ return getHibernateTemplate().save(entity); } }

 

 

 
  

 

测试server:我们在两个需要事物处理的调用之间抛出异常:

public class TestSH { private Dao dao; public void save() throws MyE{ A a = new A(); a.setAname("aname"); a.setAnum(1); dao.save(a); if(true){ throw new MyE("************异常*************"); } A a1 = new A(); a1.setAname("aname1"); a1.setAnum(1); dao.save(a1); }..get set...

 

 

 
  

 

 在这说明需要抛出RuntimeException(或者子类)或者Exception的子类,如果抛出Exception将spring将不能对他进行自动回滚,需要我们在文件中配置,如下:

<tx:.... rollback-for="java.lang.Exception"/>//也就是spring所谓的 Winning rollback rule

事务配置:

<tx:advice id="txAdviceService" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="load*" read-only="true"/> <tx:method name="find*" read-only="true"/> <tx:method name="list*" read-only="true"/> <tx:method name="check*" read-only="true"/> <tx:method name="browse*" read-only="true"/> <tx:method name="search*" read-only="true"/> <tx:method name="*" read-only="false" rollback-for="java.lang.Exception"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="actionMethods" expression="execution(* com.action.*.*(..))"/> <aop:advisor advice-ref="txAdviceService" pointcut-ref="actionMethods"/> </aop:config> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean>

 

 

 
  

 

 

 测试配置如下:

<bean id="dao" class="com.server.Dao"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <bean id="test" class="com.action.TestSH"> <property name="dao" ref="dao"></property> </bean>

 

 

 
  

 

 说明: 需要自动事务的类必须是spring可加载的也就是需要在文件中配,否则就会出现事务不起作用的情况 具体的讨论文章可见javaeye上

 

 

 测试类:

public class Test { private static TestSH testsh; static{ System.out.println("init....."); ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"applicationContext-*.xml","applicationContext.xml"}); testsh = (TestSH) ctx.getBean("test"); } public static void main(String[] args) { try { testsh.save(); } catch (MyE e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

 

 

 
  

 

 最终控制台信息:

09-08-31 16:52:06,187 DEBUG (org.springframework.transaction.interceptor.TransactionInterceptor:282) - Getting transaction for [com.action.TestSH.save] 2009-08-31 16:52:06,187 DEBUG (org.springframework.transaction.support.TransactionSynchronizationManager:140) - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@191e4c] for key [org.hibernate.impl.SessionFactoryImpl@11415c8] bound to thread [main] 2009-08-31 16:52:06,187 DEBUG (org.springframework.transaction.support.TransactionSynchronizationManager:140) - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@191e4c] for key [org.hibernate.impl.SessionFactoryImpl@11415c8] bound to thread [main] 2009-08-31 16:52:06,187 DEBUG (org.springframework.orm.hibernate3.HibernateTemplate:364) - Found thread-bound Session for HibernateTemplate Hibernate: insert into A (aname, anum, version) values (?, ?, ?) 2009-08-31 16:52:06,234 DEBUG (org.springframework.orm.hibernate3.HibernateTemplate:388) - Not closing pre-bound Hibernate Session after HibernateTemplate 2009-08-31 16:52:16,234 DEBUG (org.springframework.transaction.interceptor.TransactionInterceptor:327) - Completing transaction for [com.action.TestSH.save] after exception: com.exc.MyE: ************异常************* 2009-08-31 16:52:16,234 DEBUG (org.springframework.transaction.interceptor.RuleBasedTransactionAttribute:130) - Applying rules to determine whether transaction should rollback on com.exc.MyE: ************异常************* 2009-08-31 16:52:16,234 DEBUG (org.springframework.transaction.interceptor.RuleBasedTransactionAttribute:148) - Winning rollback rule is: RollbackRuleAttribute with pattern [java.lang.Exception] 2009-08-31 16:52:16,234 DEBUG (org.springframework.orm.hibernate3.HibernateTransactionManager:846) - Triggering beforeCompletion synchronization 2009-08-31 16:52:16,234 DEBUG (org.springframework.orm.hibernate3.HibernateTransactionManager:751) - Initiating transaction rollback 2009-08-31 16:52:16,234 DEBUG (org.springframework.orm.hibernate3.HibernateTransactionManager:593) - Rolling back Hibernate transaction on Session [org.hibernate.impl.SessionImpl@4298e] 2009-08-31 16:52:16,265 DEBUG (org.springframework.orm.hibernate3.HibernateTransactionManager:875) - Triggering afterCompletion synchronization 2009-08-31 16:52:16,265 DEBUG (org.springframework.transaction.support.TransactionSynchronizationManager:276) - Clearing transaction synchronization 2009-08-31 16:52:16,265 DEBUG (org.springframework.transaction.support.TransactionSynchronizationManager:193) - Removed value [org.springframework.orm.hibernate3.SessionHolder@191e4c] for key [org.hibernate.impl.SessionFactoryImpl@11415c8] from thread [main] 2009-08-31 16:52:16,265 DEBUG (org.springframework.orm.hibernate3.HibernateTransactionManager:653) - Closing Hibernate Session [org.hibernate.impl.SessionImpl@4298e] after transaction 2009-08-31 16:52:16,265 DEBUG (org.springframework.orm.hibernate3.SessionFactoryUtils:771) - Closing Hibernate Session com.exc.MyE: ************异常************* at com.action.TestSH.save(TestSH.java:29)

 

 

 
  

 

 另外针对事务配置可以在最外层的业务层设置,防止嵌套获取事务的情况(当然不会出现实务问题)。

 



你可能感兴趣的:(hibernate spring 事务)