Spring 事务管理及配置

声明:这是转载的

根据网友资料整理

spring几种事务配置

http://www.iteye.com/topic/615413

Spring 配置 事务的几种方式

http://www.iteye.com/topic/1123347


spring 事务详解和配置

http://vallen870201.iteye.com/blog/1064494


正文:

两种Spring事务管理方式:编程式、声明式。

大多数Spring用户选择声明式事务管理,这是最少影响应用代码的选择,因而这是和非侵入性的轻量级容器的观念是一致的。


先定义一个DAO接口及实现类:

import com.lgh.hibernate.UserTable;

public interface IUserDao {
 public void insertUser(UserTable user);
}

实现类:

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.lgh.hibernate.UserTable;

public class UserDaoImpl extends HibernateDaoSupport implements IUserDao{
	public void insertUser(UserTable user) {
		getHibernateTemplate().saveOrUpdate(user);
	}
}

第一种
为每个bean设置一个代理,这种是根据具体需求来定,如要对具体到每个交易进行事务操作的话,这个方式是最合适的;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!-- 每个bean都有一个代理 -->
<beans>
	<!-- sessionFactory相当于spring datasource -->
 	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />  
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>  
	<!-- 定义事务管理器(声明式的事务) -->  
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <!-- 配置DAO -->
    <bean id="userDao" class="org.lgh.spring.transaction2.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    
    <!-- 每个bean都有一个代理 <property name="target" ref="userDaoTarget" />  -->
    <bean id="userDaoProxy"  
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
           <!-- 配置事务管理器 -->  
           <property name="transactionManager" ref="transactionManager" />     
        <property name="target" ref="userDao" />  
         <property name="proxyInterfaces" value="org.lgh.spring.transaction2.IUserDao" />
        <!-- 配置事务属性 -->  
        <property name="transactionAttributes">  
            <props>  
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>  
        </property>  
    </bean>  
</beans>


第二种:
所有的bean共享一个代理

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
  <!-- 所有的bean共享一个代理-->
<beans>
	<bean id="sessionFactory"  
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />  
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>  

    <!-- 定义事务管理器(声明式的事务) -->  
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <!-- 所有的bean共享一个代理/>  -->
    <bean id="transactionBase"  
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"  
            lazy-init="true" abstract="true">  
        <!-- 配置事务管理器 -->  
        <property name="transactionManager" ref="transactionManager" />  
        <!-- 配置事务属性 -->  
        <property name="transactionAttributes">  
            <props>  
                <prop key="*">PROPAGATION_REQUIRED</prop>  
            </props>  
        </property>  
    </bean>    
   
    <!-- 配置DAO -->
    <bean id="userDao" class="org.lgh.spring.transaction3.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
     <!-- 所有的bean共享一个代理/>  -->
    <bean id="userDaoProxy" parent="transactionBase" >  
        <property name="target" ref="userDao" />   
    </bean>

</beans>

第三种:
使用拦截器 来配置你的事务,这个主要是进行一些方法调用前后进行一些其他事件的处理,如进行权限检查等...
代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
 
<!-- 使用拦截器 -->

<beans>
	<bean id="sessionFactory"  
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />  
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>  

    <!-- 定义事务管理器(声明式的事务) -->  
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean> 
   
    <bean id="transactionInterceptor"  
        class="org.springframework.transaction.interceptor.TransactionInterceptor">  
        <property name="transactionManager" ref="transactionManager" />  
        <!-- 配置事务属性 -->  
        <property name="transactionAttributes">  
            <props>  
                <prop key="*">PROPAGATION_REQUIRED</prop>  
            </props>  
        </property>  
    </bean>
    <bean name="logger" class="org.lgh.spring.transaction4.SpringAOPInterceptor">
    	
    </bean>
    
    
    <bean id="logBeforeAdvice" class="com.test.advices.LogBeforeAdvice">
	</bean>
	
    <!-- 定义BeanNameAutoProxyCreator,该bean是个bean后处理器,无需被引用,因此没有id属性   
	这个bean后处理器,根据事务拦截器为目标bean自动创建事务代理    -->
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">  
        <!-- 加上此句就不会抛出 $Proxy cannot be cast的异常啦-->
        <property name="proxyTargetClass">
        	  <value>true</value>
        </property>  
        <property name="beanNames">  
            <list>  
            <!-- *Dao对应下面的userDao要对它进行拦截-->
                <value>userDao</value>
            </list>  
        </property>  
        <property name="interceptorNames">  
            <list>  
                <value>transactionInterceptor</value>  
                <value>logBeforeAdvice</value>
            </list>  
        </property>  
    </bean>  
  
    <!-- 配置DAO -->
    <bean id="userDao" class="org.lgh.spring.transaction4.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <!-- 服务层 service-->
     <bean id="userService" class="org.lgh.spring.transaction4.UserServiceImpl">
        <property name="userDao" ref="userDao" />
    </bean>
</beans>

第四种:

使用aop:config配置方式

<?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:context="http://www.springframework.org/schema/context"
    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-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">


 <context:annotation-config />
    <context:component-scan base-package="org.lgh.spring.transaction5" />

    <bean id="sessionFactory"  
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />  
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>  

    <!-- 定义事务管理器(声明式的事务) -->  
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
     
     <!-- 定义事务 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>
    
    <!-- 定义切面 -->
    <aop:config   proxy-target-class="true" >
    	
        <aop:pointcut id="interceptorPointCuts"
            expression="execution(* org.lgh.spring.transaction5.*.*(..))" />
        <aop:advisor advice-ref="txAdvice"
            pointcut-ref="interceptorPointCuts" />        
    </aop:config>     
     
    <!-- 配置DAO -->
    <bean id="userDao" class="org.lgh.spring.transaction5.UserDaoImpl">

        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
     

    
</beans>

第五种就是采用全注解方式:
代码如下:

<?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:context="http://www.springframework.org/schema/context"
    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-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

 <context:annotation-config />
    <context:component-scan base-package="org.lgh.spring.transaction6" />
    <!-- 支持  @Transactional 标记 --> 
    <tx:annotation-driven proxy-target-class ="true" transaction-manager="transactionManager"/>

    <bean id="sessionFactory"  
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />  
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    </bean>  

    <!-- 定义事务管理器(声明式的事务) -->  
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- 配置DAO -->
    <bean id="userDao" class="org.lgh.spring.transaction6.UserDaoImpl">
    	
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
</beans>

所用到的jar包

Spring 事务管理及配置_第1张图片


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="show_sql">
			true
		</property>
		
		<property name="dialect">
			org.hibernate.dialect.OracleDialect
		</property>
		
		<property name="connection.driver_class">
			oracle.jdbc.driver.OracleDriver
		</property>
		
		<property name="connection.url">
			jdbc:oracle:thin:@localhost:1521:orcl
		</property>
		
		<property name="connection.username">用户名</property>
		<property name="connection.password">密码</property>
		
		<!-- 连接池启动时的初始值 -->  
        <property name="initialSize">10</property>  
        <!-- 连接池的最大值 -->  
        <property name="maxActive">10</property>  
        <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->  
        <property name="maxIdle">20</property>  
        <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->  
        <property name="minIdle">10</property>  
        <property name="defaultAutoCommit">true</property>
		
		
		<!-- 事务管理类型,这里我们使用JDBC Transaction
		<property name="hibernate.transaction.factory_class">net.sf.hibernate.transaction.JDBCTransactionFactory
		</property> -->
		<mapping resource="com/lgh/hibernate/UserTable.hbm.xml" />

	</session-factory>

</hibernate-configuration>


【附录】

事务传播行为种类
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,
它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:
表1事务传播行为类型
事务传播行为类型
说明
PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。


=========================================

2012-11-15 补充

@Transactional

一般是在涉及事务管理的Service类前出现

@Repository

一般在Dao类前出现

======================================

2013-3-2 补充

还有另外一种方法 是 

通过继承Spring类库中的HibernateDaoSupport 类,定义ThreadLocal对象来实现

commit() closeSession()  excuteSql(String sql) openTransaction() saveOrUpdate(Object po) 等方法

public class SpringHibernateDao extends HibernateDaoSupport implements IDao {
	private final static ThreadLocal localSession=new ThreadLocal();
	private final static ThreadLocal localTransaction=new ThreadLocal();
	private final static ThreadLocal localAuto=new ThreadLocal();
	
	public SpringHibernateDao()
	{
		this.setAutoSession(true);
	}

。。。

public boolean closeSession() throws Exception {
		try {
			if (getLocalSession() != null && getLocalSession().isOpen()) {
				getLocalSession().close();
			}
			return true;
		} catch (Exception e) {
			throw e;
		}
	}

	public void commit() throws Exception {
		try {
			if (this.getLocalSession() != null && this.getLocalSession().isOpen()
					&& getLocalTransaction() != null && !getLocalTransaction().wasCommitted()) {
				
				getLocalTransaction().commit();
			}
		} catch (Exception e) {

			throw new Exception("无法提交,Commit错误!", e);

		}
	}

。。。

public boolean openTransaction() throws Exception {
		try {

			if (this.getLocalSession() != null && this.getLocalSession().isOpen()) {
				setLocalTransaction(this.getLocalSession().beginTransaction());
				getLocalTransaction().begin();

				return true;
			} else {
				return false;
			}
		} catch (Exception ex) {
			throw new Exception("无法启动事务");
		}
	}

	public void rollback() throws Exception {
		try {
			if (this.getLocalSession() != null && this.getLocalSession().isOpen()
					&& getLocalTransaction() != null && !getLocalTransaction().wasRolledBack()) {
				getLocalTransaction().rollback();
			}
		} catch (Exception ex) {
			throw new Exception("无法回滚事务");
		}
	}

(完)

你可能感兴趣的:(DAO,spring,bean,Class,encoding)