问题描述如下
1,Spring读取tomcat的jndi数据源
2,注入给hibernate的sessionfactory
3,在spring中配置声明式事物处理
但是确没有生效,就是给DAO包中所有的方法配置事物管理,包的路径如下
com.osisg.DAO 下面是各种各样的数据库操作类,其中一个为
public class RegisterDAOImp implements IRegisterDAO {
//由Spring进行托管和注入
private SessionFactory sessionFactory;

public SessionFactory getSessionFactory() {
return sessionFactory;
} public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
} public String register(String username, String password) {
// TODO 用户注册接口的实现类

String returnValue="数据库漏判";
//下面的代码用来测试声明式的事务管理是否好用,就省略了开始事务和提交事务的需求
Session session =sessionFactory.openSession();

Userinfo userinfo1=new Userinfo();
userinfo1.setUsername("test1");
userinfo1.setPassword("test1");
Userinfo userinfo2=new Userinfo();
userinfo2.setUsername("test2"); userinfo2.setPassword("1234567890123456789012345");
session.save(userinfo1);
session.save(userinfo2);
session.close();
return returnValue;
}
}
   注解:userinfo1是可以保存进去的,但是userinfo2的长度大于数据库的varchar(20),所以无法保存下去,因此
          如果是一个事物下的话,那么这两个数据就都保存不进去,spring的配置文件如下,最下面是声明式事物的配置方法<?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: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.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- 使用Tomcat提供的JNDI -->
<!-- 设定dataSource -->
<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:/comp/env/jdbc/spring</value>
</property>
</bean>
<!-- 设定transactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="myDataSource"/>
</property>
</bean>
<!-- 下面是各种DAO的Spring注入方式 -->
<bean id="logindao" class="com.osisg.DAO.LoginDAOImp">
<property name="sessionFactory">
<ref bean="mySessionFactory"/>
</property>
</bean>
<bean id="registerdao" class="com.osisg.DAO.RegisterDAOImp">
<property name="sessionFactory">
<ref bean="mySessionFactory"/>
</property>
</bean>

<!-- 下面是MyEclipse自动生成的 -->
<!-- 这个已经在最上面开始的时候配置完毕,下次可以不配置上面而让系统自动生成下面的这个,用的是tomcat的jndi数据源
 bean id="dataSource_beanid"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="dataSource"></property>
</bean -->
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="myDataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.SQLServerDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>com/osisg/po/Userinfo.hbm.xml</value>
</list>
</property>
</bean>
<!-- 上面是MyEclipse自动生成的 hibernateProperties,mappingResource,dataSource -->

<!-- 下面配置Spring的声明式事物管理,接下来配置的是TransactionManager -->
<bean id="myTxManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<!-- 下面配置 事物策略 -->
<tx:advice id="txAdvice" transaction-manager="myTxManager">
<tx:attributes>
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- AOP的配置,通过AOP实现Java对象方法级的事务管理,配置的方法于普通的AOP没有区别 -->
<aop:config>
<aop:pointcut id="productServiceMethods"
expression="execution(* com.osisg.DAO.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
</aop:config>

</beans>
但是实际运行当中,并没有起到事物回滚的效果,userinfo1直接保存到了数据库中,也就是说声明式事物管理没有生效

解决方案 »

  1.   

    请根据下面代码适当改一下,如下代码非常通用,扩展性也很好。
    <bean id="DataSourceTransactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
    </bean>
    <bean id="txProxyTemplate" abstract="true"
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager" ref="transactionManager"/>
            <property name="transactionAttributes">
                <props>
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
                    <prop key="remove*">PROPAGATION_REQUIRED</prop>
                    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory">
            </property>
    </bean>
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
            </props>
            </property>
    </bean>
    <bean id="registerdao" parent="txProxyTemplate">
           <property name="target"> 
               <bean class="com.osisg.DAO.RegisterDAOImp"/>
           </property>
           <property name="transactionAttributes">
                <props>
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
                    <prop key="remove*">PROPAGATION_REQUIRED</prop>
                    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
    </bean>
      

  2.   

    这个不是用的aop编写的我想要用aop编写的例子,不过仍然感谢你啦
      

  3.   

    不要直接用sessionFactory获取session来执行操作,你的Dao对象继承HibernateDaoSupport,然后用回调HibernateCallback试一试