yangjun8493
2011-08-15 08:54 阅读 236
已采纳

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条回答 默认 最新

  • 已采纳
    s929498110 s929498110 2011-08-15 11:41

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

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

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

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

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

    点赞 评论 复制链接分享
  • renpeng301 renpeng301 2011-08-15 09:13

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

    点赞 评论 复制链接分享
  • bolang102020 bolang102020 2011-08-15 09:35

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

    点赞 评论 复制链接分享
  • renpeng301 renpeng301 2011-08-15 11:42

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

    点赞 评论 复制链接分享
  • s929498110 s929498110 2011-08-15 11:44

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

    点赞 评论 复制链接分享
  • s929498110 s929498110 2011-08-15 12:19

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

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

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

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

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

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

    点赞 评论 复制链接分享
  • bolang102020 bolang102020 2011-08-15 13:48

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

    点赞 评论 复制链接分享
  • bolang102020 bolang102020 2011-08-15 14:03

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

    点赞 评论 复制链接分享
  • bolang102020 bolang102020 2011-08-15 14:08

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

    点赞 评论 复制链接分享

相关推荐