我用的是Spring+hibernate+mysql.
mysql是innodb,自动提交设置为:set autocommit=0;支持数据库事务。
我抛出的异常是runtimeException.
问题就是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/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">


<!-- hibernate start -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/hbtest" />
<property name="username" value="root" />
<property name="password" value="sa" />
<property name="maxActive" value="100" />
<property name="minIdle" value="30" />
<property name="maxWait" value="500" />
</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.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>com/test/entity/User.hbm.xml</value>
<value>com/test/entity/Log.hbm.xml</value>
</list>
</property>
</bean>
 
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
   <property name="sessionFactory">
    <ref bean="sessionFactory"/>
   </property>
</bean>
<!-- 配置事务的传播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
   <tx:attributes>
    <tx:method name="add*" propagation="REQUIRED"/>
    <tx:method name="del*" propagation="REQUIRED"/>
    <tx:method name="modify*" propagation="REQUIRED"/>
    <tx:method name="*" read-only="true"/>
   </tx:attributes>
</tx:advice>
<!--那些类的哪些方法参与事务-->
<aop:config>
   <aop:pointcut id="allManagerMethod" expression="execution(* com.test.service.*.*(..))"/>
   <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/>
</aop:config> 

<bean id="userService" class="com.test.serivce.UserService">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
 
</beans>

解决方案 »

  1.   

    不知道 你有沒有把Spring 的 asm-2.3....jar 那個包刪掉? 
    那個包跟hibernate 有衝突 !!!!
      

  2.   

    如果要用SPRING的事务应该是删除asm那个包,而不是asm-2.3...jar
    UserService代码:package com.test.serivce;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import com.test.entity.Log;
    import com.test.entity.User;public class UserService extends HibernateDaoSupport{

    public void addUser(User user) {

    this.getHibernateTemplate().save(user);
    Log log = new Log();
    log.setLogCont(new StringBuffer().append(user.getUsername()).append("is creating..new").toString());
    this.getHibernateTemplate().save(log);
    throw new java.lang.RuntimeException();
    }}测试代码:package com.test;import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;import com.test.entity.User;
    import com.test.serivce.UserService;/**
     * @author wangking E-mail:[email protected]
     * @version 创建时间:2009-9-7 上午01:49:20
     * 类说明
     */
    public class Test {

    public static void main(String[] args) {
    BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserService service = (UserService)factory.getBean("userService");
    User user = new User();
    user.setUsername("wangking");
    service.addUser(user);
    }

    }
      

  3.   


            this.getHibernateTemplate().save(user);
            Log log = new Log();
            log.setLogCont(new StringBuffer().append(user.getUsername()).append("is creating..new").toString());
            this.getHibernateTemplate().save(log);
            throw new java.lang.RuntimeException();
    按你的想法 执行完save(log) 不就要抛个RuntimeException吗?
      

  4.   

    注入错误    <bean id="userService" class="com.test.serivce.UserService">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>JavaBean规范
      

  5.   

    spring 接口注入 构造方法注入 setter方法注入
      

  6.   

    <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.RuntimeException"/>
      

  7.   

    不是注入错误,UserService 继承了HibernateDaoSupport类,HibernateDaoSupport类中有setSessionFactory方法
      

  8.   

    应该是使用Session的问题save(user)后 session就已经关闭了save(log)就不在同一个Session中了因为默认是openSession() 一个事物 打开一个session可以把两个session绑定在一起 同时打开 关闭就是那个getCurrentSession () 使用当前的session
    <property name="hibernate.current_session_context_class">thread</property>
    绑定当前Session到线程中 以保证是同一个Session
      

  9.   

    我测试过。我把配置的方式改为注解方式,能成功回滚。事务起了作用。那证明不是MYSQL的问题,只有一个问题,配置文件问题。而配置文件我加上<prop key="hibernate.current_session_context_class">thread</prop>
    还是不能回滚,大家来测试看一下问题会出在哪呢?
      

  10.   

    <bean id="userService" class="com.test.serivce.UserService">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    是一个底层类?
    在事务的传播属性里加个rollback-for这个属性试试
      

  11.   

    rollback-for试过了的。默认不加就是RuntimeException
      

  12.   

    hibernate.current_session_context_class:意思是hibernate的当前主体类,你有thread这类,发过来看看
      

  13.   

    应该是使用Session的问题
    save(user)后 session就已经关闭了
    save(log)就不在同一个Session中了
    因为默认是openSession() 一个事物 打开一个session可以把两个session绑定在一起 同时打开 关闭就是那个getCurrentSession () 使用当前的session
    <property name="hibernate.current_session_context_class">thread </property>
    绑定当前Session到线程中 以保证是同一个Session 正解
      

  14.   

    我配置了<property name="hibernate.current_session_context_class">thread </property> 的、但是还是不能回滚。
        <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.current_session_context_class">thread</prop> 
                    <prop key="hibernate.show_sql">true</prop>
                </props>
            </property>
            <property name="mappingResources">
                <list>
                    <value>com/test/entity/User.hbm.xml</value>
                    <value>com/test/entity/Log.hbm.xml</value>
                </list>
            </property>
        </bean>
      

  15.   


    public class UserDaoImpl implements UserDao{ public void addUser(User user) {
    Session session = null;
    Transaction ts = null;

    try {
    //session = HibernateSessionFactory.getSession();
                            //HibernateSessionFactory 自定义工具类
    session = HibernateSessionFactory.getSessionFactory().getCurrentSession();
    ts = session.beginTransaction();

    session.save(user);

    Log log = new Log();
                            log.setLogCont(new StringBuffer()
                               .append(user.getUsername())
                               .append("is creating..new").toString());

    LogDao ldao = new LogDaoImpl();
    ldao.saveLog(log);                        throw new RuntimeException(); ts.commit();
    } catch (HibernateException e) {
    if(ts.isActive()){
    ts.rollback();
    }
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (Exception e){
    e.printStackTrace();
    } finally{
    HibernateSessionFactory.close(session);
    }

    }}
    public class LogDaoImpl implements LogDao { public void saveLog(Log log) {
    //HibernateSessionFactory.getSession().save(log);
    HibernateSessionFactory.getSessionFactory().getCurrentSession().save(log);
    }}
    我的没问题啊???
      

  16.   

    绑定过后 取Session就要从线程里面取啦
    你那样还是取的独立的Session啊
      

  17.   

    貌似没啥问题
    这样改下试试  <!-- 配置事务的传播特性 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
           <tx:attributes>
            <tx:method name="get*" propagation="REQUIRED" read-only="true“/>
             <tx:method name="*" read-only="false"/>
           </tx:attributes>
        </tx:advice>