先看两个定义关于事务传播属性的:
REQUIRED:业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到该事务,否则为自己创建一个新的事务。
NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行。下面测试传播属性NOT_SUPPORTED在事务中被调用的情况:
配置文件:
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-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
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-2.5.xsd">
  
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<!-- 指定连接数据库的驱动 -->
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
<!-- 指定连接数据库的URL -->
<property name="jdbcUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" />
<!-- 指定连接数据库的用户名 -->
<property name="user" value="spring" />
<!-- 指定连接数据库的密码 -->
<property name="password" value="aaa519760" />
<!-- 指定连接数据库连接池的最大连接数 -->
<property name="maxPoolSize" value="40" />
<!-- 指定连接数据库连接池的最小连接数 -->
<property name="minPoolSize" value="1" />
<!-- 指定连接数据库连接池的初始化连接数 -->
<property name="initialPoolSize" value="1" />
<!-- 指定连接数据库连接池的连接的最大空闲时间 -->
<property name="maxIdleTime" value="20" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>com/zjlolife/hibernate/domain/Person.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
hibernate.hbm2ddl.auto=create
hibernate.show_sql=true
hibernate.format_sql=true
</value>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="personService" class="com.zjlolife.hibernate.service.impl.PersonServiceBean"/>
<!-- 事务注册annation解析器 -->
<tx:annotation-driven transaction-manager="txManager" />
<!-- context注解,代表注册多种@resource,还有其他的解析器 -->
 <context:annotation-config/>
</beans>然后service代码:package com.zjlolife.hibernate.service.impl;import java.sql.SQLException;
import java.util.List;import javax.annotation.Resource;import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import com.zjlolife.hibernate.domain.Person;
import com.zjlolife.hibernate.service.PersonService;@Transactional
public class PersonServiceBean implements PersonService { @Resource
private SessionFactory sessionFactory;

private HibernateTemplate getHibernateTemplate() {
return new HibernateTemplate(sessionFactory);
}
    
@Transactional(propagation=Propagation.REQUIRED)
public void save(final Person person) {
getHibernateTemplate().execute(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException {
   try {
System.out.println("========="+session.connection().getAutoCommit());
System.out.println(session);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
session.save(person);
return null;
}
}); //按照事务传播的概念,save()为不需要事务,那么在当前事务执行到save()的时候会挂起,因此我觉得当前事务失败应该不会影响save()方法的执行,
    //可是结果却是影响了!save()方法中执行也失败了
save();

throw new RuntimeException("抛出例外");
}

@Transactional(propagation=Propagation.NOT_SUPPORTED)
public void save() {
Person person = new Person("zjlolife11111");
getHibernateTemplate().save(person);

} }然后就是测试代码:
package com.zjlolife.hibernate.test;import javax.transaction.Transaction;import junit.framework.TestCase;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.zjlolife.hibernate.domain.Person;
import com.zjlolife.hibernate.service.PersonService;public class SpringTest extends TestCase { public void test1() {
Person person = new Person("zjlolife008");
ApplicationContext cxt = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) cxt.getBean("personService");
personService.save(person);

}


}
然后控制台输出情况:
=========false
SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[]])
Hibernate: 
    select
        max(id) 
    from
        t_personjava.lang.RuntimeException: 抛出例外
at com.zjlolife.hibernate.service.impl.PersonServiceBean.save(PersonServiceBean.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy7.save(Unknown Source)
at com.zjlolife.hibernate.test.SpringTest.test1(SpringTest.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)按照事务传播属性来看的话,save()方法应该会执行成功,但是却没有!我觉得这与spring获取session有很大的关系。save(Person  person)调用save()的时候,save()方法中的session是从当前线程中取得的,由于存在事务控制,因此不会调用HibernateTemplate的flushIfNecessary中的flush方法,这点源代码里有,flush操作会在事务提交的时候进行,因此没有看到发出语句。
 出现这种情况的主要原因,我觉得是与spring如何获取session的原因
   希望大家交流下,给出合理的见解