为了保持数据的一致性和完整性,在编程中通常会引用到事务的概念。这里就不对事务做一一讲解,大家可以看我前面的一篇讲事务的博客java JDBC事务和JTA事务详解。事务一般有两种:编程式事务和声明式事务;编程式事务就是将事务处理放在程序中,而声明式事务则是通过配置文件或者注解进行操作。
在Spring中我们通常使用的是声明式事务通过和Hibernate的集成去完成hibernate事务配置。
其实配置Hibernate事务的核心就一种:
(1)、配置SessionFactory;
(2)、配置事务容器;
(3)、配置事务规则;
(4)、配置事务入口;
下面我们看看通常Hibernate事务配置使用的几种方式:
第一种:代理;
<!-- 配置事务容器 --> <beanid="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <propertyname="sessionFactory"ref="sessionFactory"/> </bean> <!-- 定义事务规则 --> <beanid="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true"> <propertyname="transactionManager"ref="transactionManager"/> <propertyname="transactionAttributes"> <props> <!-- ,回滚为-,不回滚为+ --> <propkey="add*">PROPAGATION_REQUIRED,-Exception</prop> <propkey="modify*">PROPAGATION_REQUIRED,+MyException</prop> <propkey="del*">PROPAGATION_REQUIRED</prop> <propkey="*">READONLY</prop> </props> </property> </bean> <!-- 定义事务入口 --> <beanid="userDaoProxy"parent="transactionProxy"> <propertyname="target"ref="userDao"></property> </bean>
第二种:拦截器
<!-- 配置事务容器 --> <beanid="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <propertyname="sessionFactory"ref="sessionFactory"/> </bean> <!-- 定义事务规则 --> <beanid="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <propertyname="transactionManager"ref="transactionManager"/> <propertyname="transactionAttributes"> <props> <!-- 回滚为-,不回滚为+ --> <propkey="add*">PROPAGATION_REQUIRED,-Exception</prop> <propkey="modify*">PROPAGATION_REQUIRED,+MyException</prop> <propkey="del*">PROPAGATION_REQUIRED</prop> <propkey="*">READONLY</prop> </props> </property> </bean> <!-- 定义事务入口 --> <beanid="proxyFactory" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <propertyname="interceptorNames"> <list> <value>transactionInterceptor</value> </list> </property> <propertyname="beanNames"> <list> <value>*Dao</value> </list> </property> <!--使用接口时--> <property name="proxyTargetClass"> <value>true</value> </property> </bean>
第三种:利用注解
<!-- 开户事务注解功能 --> <tx:annotation-driventransaction-manager="transactionManager"/>
首先在配置文件中写入该语句,打开注解功能,然后利用@Transactional对类或者方法进行标记,如果标记在类上,每次此类中的所有方法都进行事务回滚处理,在类中定义Transactional的时候,它有propagation、rollbackFor、noRollbackFor等属性,此属性是用来定义事务规则,而定义到哪里,哪里就是事务的入口。
第四种:配置SessionFactory ----配置会话工厂
<!-- 配置数据源 --> <beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <propertyname="driverClassName"value="com.mysql.jdbc.Driver"></property> <propertyname="url"value="jdbc:mysql://localhost:3306/hibernate_cache"></property> <propertyname="username"value="root"></property> <propertyname="password"value="admin"></property> </bean> <!-- 2.2、配置SessionFactory --> <beanid="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <propertyname="dataSource"ref="dataSource"></property> <propertyname="hibernateProperties"> <props> <propkey="hibernate.hbm2ddl.auto">update</prop> </props> </property> <propertyname="mappingLocations"> <list> <value>classpath:实体对应xml的路径</value> </list> </property> </bean> <!--到这里Hibernate就成功的将SessionFactory交给了Spring来管理。 然后利用tx标签配置事务。--> <!-- 配置事务容器 --> <beanid="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <propertyname="sessionFactory"ref="sessionFactory"/> </bean> <!-- 定义事务规则 --> <tx:adviceid="txAdvice"transaction-manager="transactionManager"> <tx:attributes> <tx:methodname="add*"propagation="REQUIRED"/> <tx:methodname="modify*"propagation="REQUIRED"/> <tx:methodname="del*"propagation="REQUIRED"/> <tx:methodname="*"propagation="REQUIRED"read-only="true"/> </tx:attributes> </tx:advice> <!-- 定义事务入口 --> <aop:config> <aop:pointcutid="allDaoMethod"expression="execution(* com.jianxin.dao.*.*(..))" /> <aop:advisoradvice-ref="txAdvice"pointcut-ref="allDaoMethod"/> </aop:config>