我用的是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>
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>
那個包跟hibernate 有衝突 !!!!
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);
}
}
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吗?
<property name="sessionFactory" ref="sessionFactory" />
</bean>JavaBean规范
<property name="hibernate.current_session_context_class">thread</property>
绑定当前Session到线程中 以保证是同一个Session
还是不能回滚,大家来测试看一下问题会出在哪呢?
<property name="sessionFactory" ref="sessionFactory" />
</bean>
是一个底层类?
在事务的传播属性里加个rollback-for这个属性试试
save(user)后 session就已经关闭了
save(log)就不在同一个Session中了
因为默认是openSession() 一个事物 打开一个session可以把两个session绑定在一起 同时打开 关闭就是那个getCurrentSession () 使用当前的session
<property name="hibernate.current_session_context_class">thread </property>
绑定当前Session到线程中 以保证是同一个Session 正解
<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>
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);
}}
我的没问题啊???
你那样还是取的独立的Session啊
这样改下试试 <!-- 配置事务的传播特性 -->
<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>