配制无限制的Spring事务管理

目录:V1.0
1.旧时的痛
2.光明来临前的黑暗
3.欢迎救世主


注:可自由转载,转载时需说明出处并请保持原样。

1.旧时的痛

为什么说配制无限制的Spring事务管理呢,估计肯定有哪位高手看过标题之后就会奇怪,配制事务管理还要有什么限制吗?
当然对您这样的高手当然是运用自如。但是还是和很多初识者甚至有很长的工作经验的朋友的老鸟对Spring配制只停留在spring1.x
阶段,并且仅限于配制Spring+Hibernate的事务管理。
最经典的Spring+Hibernate的配制是这样的:

<!--   数据源  -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@192.168.0.150:1521:cisfedb"/>
        <property name="username" value="draftsa"/>
        <property name="password" value="draftsa"/>
        <property name="maxActive" value="100"/>
        <property name="maxIdle" value="30"/>
        <property name="maxWait" value="1000"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="removeAbandoned" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>
    </bean>
<!--   工厂  -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="lobHandler">
            <ref bean="lobHandler"/>
</property>
<property name="mappingResources">
<list>
<value>com/ecds/hibernate/EcdAuthlistdata.hbm.xml</value>
<value>com/ecds/hibernate/PcdRediscountwithcb.hbm.xml</value>
</list>
</bean>
<!-- 事务管理,用的hibernate 的 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<!-- 事务代理,由spring 接管,配置性事务,aop 应用 -->
<bean id="baseTxProxy" lazy-init="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="del*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED,-Exception</prop>
</props>
</property>
</bean>

在使用时为每个service加入事务模版,其实这种方式已经很方便了,
但是限制了使用者的视野,让很多初学者误认为Spring的事务只针对Hibernate准备的。
这是Spring1.0时代的产物,深深的留下了持久层框架的烙印。

<bean id="commonService" parent="baseTxProxy">
<property name="target">
<bean class="com.ecds.service.common.impl.CommonServiceImpl">
<property name="icommonDao">
<ref bean="icommonDao"/>
</property>
</bean>
</property>
</bean>


2.光明来临前的黑暗
实际上Spring提供了多种事务管理器以供使用,而其中的一种才是Hibernate的,如下:

事务管理器的实例

 

目标

 

Org.springframwork.jdbc.datasource.DataSourceTransactionManager

 

用DBC的 DataSource 去管理事务

 

Org.springframwork.orm.hibernate.HibernateTransactionManager

 

当持久机制是Hibernate时的事务管理器

 

Org.springframework.orm.jdoTransactionManager

 

当持久机制是JDO时的事务管理器

 

Org.springframework.transaction.jta.JtaTransactionManager

 

用JTA管理事务

 

Org.springframwork.orm.ojb.PersistenceBrokerTransactionManager

 

当持久机制是apache的OJB时的事务管理器


也就是说以下配制中的class使用不同的事务管理器可以应用在不同的持久层机制上,其中的 DataSourceTransactionManager是最为通用的管理器。
有很多人在论坛里问:在Hibernate中是这样配制事务管理的,那么在某某下是如何配制呢,问的人不深问题的本身,而是只注重于解决事情的方式上。
当然这时用数据源的方式不是用sessionFactory,这种情况下就是在Spring1.x下的通用方式。

<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>

3.欢迎救世主

下面来介绍一下在Spring2.x达到相同的通用方式,并且配制起来更简洁和灵活的方式,当然和上面一样通用的方式就要使用通用的数据源( DataSource管理器)。

<!-- 数据源 -->
<bean id="vbank_ds_master" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${vbank.master.jdbc.driverClassName}"/>
        <property name="url" value="${vbank.master.jdbc.url}"/>
        <property name="username" value="${vbank.master.jdbc.username}"/>
        <property name="password" value="${vbank.master.jdbc.password}"/>
        <property name="maxActive" value="30"/>
        <property name="maxIdle" value="10"/>
        <property name="maxWait" value="1000"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="removeAbandoned" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>
        <property name="logAbandoned" value="false"/>
        <property name="testOnBorrow" value="true"/>
        <property name="testWhileIdle" value="true"/>
        <property name="validationQuery" value="select 1"/>
        <property name="poolPreparedStatements" value="true"/>
        <property name="timeBetweenEvictionRunsMillis" value="3600000"/>
        <property name="minEvictableIdleTimeMillis" value="18000000"/>
    </bean>
<!-- AOP: Configuration and Aspects -->
<aop:config>
<aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(* *..service.*Manager.*(..))" order="0"/>
</aop:config>
<!-- 默认时自动注入id为transactionManager的事务管理器,否则需指定事务管理器id名称 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
   <tx:method name="get*" read-only="true"/>
   <tx:method name="find*" read-only="true"/>
<tx:method name="*" rollback-for="Exception,DataAccessException"/>
</tx:attributes>
</tx:advice>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="vbank_ds_master"/>
    </bean>
  
你会发现根本不需要事务模版了,由正则表达式来限定对Service的事务管理:pointcut="execution(* *..service.*Manager.*(..))" 
这样的方式是不是使你忘记了Spring中使用了什么持久层框架,是的,这时你就自由了!~
是不是想问我用了什么框架,我可以很负责任的告诉你是iBatis,你是不是没有看出来呢
下面是Service的配制,在Service中注入Dao,在Dao中注入SqlMapClientFactoryBean。
<!-- Service -->
<bean id="userAccountManager" class="com.m312.vbank.service.impl.UserAccountManagerImpl">
        <property name="genericMasterDao">    
            <bean class="com.m312.vbank.dao.ibatis.UserAccountDaoiBatis" parent="writeDao"/>     
        </property>   
        <property name="genericSlaveDao">      
            <bean class="com.m312.vbank.dao.ibatis.UserAccountDaoiBatis" parent="readDao"/>       
        </property>
    </bean>
<!-- Dao -->
<bean id="readDao" class="com.m312.vbank.dao.ibatis.GenericDaoiBatis" abstract="true">
        <!-- <property name="dataSource" ref="vbank_ds_slave"/>  -->
        <property name="sqlMapClient" ref="vbank_sqlmap_slave"/>
        <property name="sqlExecutor" ref="sqlExecutor"/>
        
    </bean>
<!-- ibatis Factory -->
<bean id="vbank_sqlmap_master" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="dataSource" ref="vbank_ds_master"/>
        <property name="configLocation" value="classpath:/sqlmap-vbank.xml"/>
    </bean>
<!-- 方言 -->
<bean id="sqlExecutor"
          class="com.m312.database.ibatis.LimitSqlExecutor">
        <property name="dialect">
            <bean class="com.m312.database.ibatis.MySQLDialect"/>
        </property>
    </bean>
好了,到些为止吧。
由于个人的技术和知识水平有限,难免有疏漏之处,请指正!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值