论坛首页 入门讨论版 Spring

一个事务管理的问题,大家有什么好的方法

浏览 126 次
该帖已经被评为新手帖
作者 正文
最后更新时间:2008-07-02
在一个方法里面,有些查询操作比较耗时,如果用@Transactional来配置事务,就会延长一个事务的执行时间,违背了事务最小化的原则。比如在一个service里面有这样一个方法:

@Transactional(readOnly = false)
public void saveSomething(Something sth) {
    //耗时的操作1
    List<A> alist = longTimeInvokeMethodA();
    //耗时的操作2
    List<B> blist = longTimeInvokeMethodB();
    for(A a:alist){
       sthDao.getSessionFactory().getCurrentSession().save(a);
    }
    for(V b:blist){
       sthDao.getSessionFactory().getCurrentSession().update(b);
    }
    sthdao.save(sth);
}

其实以上的两个操作完全可以放在这个方法的外面来执行,不过方法又需要那两个操作的返回结果,也不可能完全隔离,那就只好自己管理transaction了


public void saveSomething(Something sth) {
    //耗时的操作1
    List<A> alist = longTimeInvokeMethodA();
    //耗时的操作2
    List<B> blist = longTimeInvokeMethodB();
    sthdao.getHibernateTemplate().execute(new HibernateCallback(){                            
             public Object doInHibernate(Session session)  
                           throws HibernateException{
                  Transaction tx; 
                  try{                                        
                     tx = session.beginTransaction();
                     for(A a:alist){
                         session.save(a);
                     }
                     for(V b:blist){
                       session.update(b);
                     }
                     session.save(sth);
                     tx.commit();
                  }catch(Exception e){
                      if(tx != null)
                         tx.rollBack();
                  }                 
             }                 
      });   
}

这样写总觉得有点别扭,事务和代码混合在一起,不如交给spring来管理看着清爽。
大家有什么好办法么,或者对于这样的需求是怎样做的,我就抛砖引玉了~~
   
最后更新时间:2008-07-02
yueye 写道
在一个方法里面,有些查询操作比较耗时,如果用@Transactional来配置事务,就会延长一个事务的执行时间,违背了事务最小化的原则。比如在一个service里面有这样一个方法:

@Transactional(readOnly = false)
public void saveSomething(Something sth) {
    //耗时的操作1
    List<A> alist = longTimeInvokeMethodA();
    //耗时的操作2
    List<B> blist = longTimeInvokeMethodB();
    for(A a:alist){
       sthDao.getSessionFactory().getCurrentSession().save(a);
    }
    for(V b:blist){
       sthDao.getSessionFactory().getCurrentSession().update(b);
    }
    sthdao.save(sth);
}

其实以上的两个操作完全可以放在这个方法的外面来执行,不过方法又需要那两个操作的返回结果,也不可能完全隔离,那就只好自己管理transaction了


public void saveSomething(Something sth) {
    //耗时的操作1
    List<A> alist = longTimeInvokeMethodA();
    //耗时的操作2
    List<B> blist = longTimeInvokeMethodB();
    sthdao.getHibernateTemplate().execute(new HibernateCallback(){                            
             public Object doInHibernate(Session session)  
                           throws HibernateException{
                  Transaction tx; 
                  try{                                        
                     tx = session.beginTransaction();
                     for(A a:alist){
                         session.save(a);
                     }
                     for(V b:blist){
                       session.update(b);
                     }
                     session.save(sth);
                     tx.commit();
                  }catch(Exception e){
                      if(tx != null)
                         tx.rollBack();
                  }                 
             }                 
      });   
}

这样写总觉得有点别扭,事务和代码混合在一起,不如交给spring来管理看着清爽。
大家有什么好办法么,或者对于这样的需求是怎样做的,我就抛砖引玉了~~


被评新手了。。。晕。。。
其实想想里面东西很多的,如果在longTimeInvokeMethodA()里面做了一个update 操作,虽然这个update 可以不在一个transaction中,但是在第一个写法中,相当于加了一个互斥的锁,就会block其他的transaction,再加上一个longTimeInvokeMethodB()这个耗时的方法,系统基本就响应不了了,第二个写法就不会出现这个问题,但是事务和代码混杂了。
投新手的牛人跳一下吧,听听高见
   
0 请登录后投票
论坛首页 入门讨论版 Spring

跳转论坛:
JavaEye推荐