spring关于事务的问题

请教一下,我在整合两个框架的时候,做单元测试的时候,数据都能顺利的插入到数据库,但是用hibernate统计信息的时候,出现如下信息:
Statistics[start time=1311748544875,sessions opened=1,sessions closed=1,transactions=2,successful transactions=1,optimistic lock failures=0,flushes=1,connections obtained=1,statements prepared=4,statements closed=4,second level cache puts=0,second level cache hits=0,second level cache misses=0,entities loaded=0,entities updated=0,entities inserted=4,entities deleted=0,entities fetched=0,collections loaded=0,collections updated=0,collections removed=0,collections recreated=0,collections fetched=0,queries executed to database=0,query cache puts=0,query cache hits=0,query cache misses=0,max query time=0]

transactions=2,successful transactions=1
这里我弄不明白是什么原因。怎么事务的打开有两次,却只成功了一次。我在网上搜索了一下,没有很好的解答,但是在http://www.iteye.com/problems/60481上,这个人的问题和我一样。请大家帮助解答一下。谢谢
我把我的代码发上来请高手帮我看看:
类ServiceImpl :
@Component("service")
@Transactional
public class ServiceImpl implements Service {
@Resource(name="personDAO")
private PersonDAO personDAO;

public void service1() {
personDAO.save(new Person("yangjun"));
personDAO.save(new Person("alex"));
}
}

类PersonDAOImpl :
@Component("personDAO")
@Transactional
public class PersonDAOImpl implements PersonDAO {
@Resource(name = "sessionFactory")
private SessionFactory sessionFactory;

public void save(Person person) {
sessionFactory.getCurrentSession().persist(person);
}
}

单元测试:
@Test
public void testService1(){
try {
service.service1();
} catch (Exception e) {
System.out.println("----------"+e.getMessage());
}
Statistics st=sessionFactory.getStatistics();
System.out.println("----------------hibernate统计信息:"+st);
System.out.println("打开事务次数:"+st.getTransactionCount());
System.out.println("成功事务次数:"+st.getSuccessfulTransactionCount());
}
}

9个回答

Spring集成Hibernate时已经把SessionFactory给替换掉、
你现在使用的这个SessionFactory已经不是Hibernate自己的了
不信你可以打印 sessionFactory.getClass();

这个getCurrentSession()方法也被Spring给替换了,Spring替换的Session操作都需要Transaction、 因为Spring把Session资源都放在事务管理下的ThreadLocal中。

Spring自己隐式打开的那个事务并不会与数据库有关、 它只与获取ThreadLocal中的Session等资源有关。

所以你获取到的两个事务
一个是自己声明的、用于数据库操作的事务,它执行并且成功了
一个是Spring隐式打开用于获取与线程绑定的Session资源的,它与数据库操作无关

另外提醒:如果在Spring下使用sessionFactory.getCurrentSession()的话,如果你没有打开事务,会抛出异常的。
建议使用HibernateTemplate

8) 1。事务是否是spring管理的?
你的DAo还是用这个sessionFactory.getCurrentSession()?获取的啊·
你继承HibernateDaoSupport 这个试试
然后不知道为什么你还用了@Transactional 注解·
这个事务的注解不用了吧?

你用了spring管理,为什么还要注解一次事务?既然自动管理了,为什么还要手动开启,程序会默认你打开2次把,但是真正成功的那一次应该是spring管理的事务才对

你配置文件,是不是已经配置了事物由 spring管理??

你可以读读Spring源代码
SpringSessionContext——提供currentSession()方法接下来是
SessionFactoryUtils 接下来是
TransactionSynchronizationManager

性能上肯定不必要关心了、 Spring都是优化过的

你也可以看看Hibernate的Transaction接口实现类的源代码

Transaction就是很简单的对象, 内部大多是一些boolean变量

这种对象的创建对性能上没有任何影响。

Spring好像比较热衷于创建一些简单的辅助对象
比如HibernateTemplate的execute方法, Spring会为每个这个方法都创建一个新Session、 但是这个新Session都是ThreadLocal资源中Session的代理类。

创建这些“小对象”对性能毫无影响

打开2次没有关系,关键是事务起了作用,这些问题你自己也可以通过修改配置或者取消注解去查看是否隐式的开启了事务,就这样干吧,呵呵。。。
PS:开启事务本身损耗非常小

建议你查看帖子,通过配置而不使用注解来实现事务管理。删除就要删干净,不是只删transaction...

已加,请结贴上班!! :D

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问