JAVA认证 HibernateTemplate类使用
来源:优易学  2011-3-25 11:24:37   【优易学:中国教育考试门户网】   资料下载   IT书店

目的:使用HibernateTemplate执行execute(new HibernateCallback())方法,从HibernateCallback中得到session,在此session中做多个操作,并希望这些操作位于同一个事务中。
  如果你这样写(1):
  public static void main(String ss[]) {
  CtxUtil.getBaseManager().getHibernateTemplate().execute(new HibernateCallback() {
  public Object doInHibernate(Session session) throws HibernateException, SQLException {
  // 保存stu1
  Student stu1 = new Student();
  stu1.setName("aaaa");// 在数据库中,name字段不允许为null
  session.save(stu1);
  session.flush();//实际上,如果不是程序员"手痒"来调用这个flush(),HibernateTemplate中session的事务处理还是很方便的
  Student stu2 = new Student();
  session.save(stu2);// 没有设置name字段,预期会报出例外
  session.flush();
  return null;
  }
  });
  }
  你期望spring在执行完execute回调后,在关闭session的时候提交事务,想法是很好的,但spring并不会这么做。让我们来看看在 Hibernate的源代码中,session.beginTransation()做了什么事。看如下代码(2):
  public Transaction beginTransaction() throws HibernateException {
  errorIfClosed();
  if ( rootSession != null ) {
  // todo : should seriously consider not allowing a txn to begin from a child session
  // can always route the request to the root session
  log.warn( "Transaction started on non-root session" );
  }
  Transaction result = getTransaction();
  result.begin();
  return result;
  }
  这个方法中的result是一个org.hibernate.transaction.JDBCTransaction实例,而方法中的getTransaction()方法源代码为(3):
  public Transaction getTransaction() throws HibernateException {
  if (hibernateTransaction==null) {
  log.error(owner.getFactory().getSettings()
  .getTransactionFactory().getClass());
  hibernateTransaction = owner.getFactory().getSettings()
  .getTransactionFactory()
  .createTransaction( this, owner );
  }
  return hibernateTransaction;
  }
  再次追踪,owner.getFactory()。getSettings() .getTransactionFactory()的createTransaction()方法源代码如下(4):
  public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
  throws HibernateException {
  return new JDBCTransaction( jdbcContext, transactionContext );
  }
  它返回了一个JDBCTransaction,没什么特别的。
  在代码2中,执行了result.begin(),其实也就是JDBCTransaction实例的begin()方法,来看看(5):
  public void begin() throws HibernateException {
  if (begun) {
  return;
  }
  if (commitFailed) {
  throw new TransactionException("cannot re-start transaction after failed commit");
  }
  log.debug("begin");
  try {
  toggleAutoCommit = jdbcContext.connection().getAutoCommit();
  if (log.isDebugEnabled()) {
  log.debug("current autocommit status: " + toggleAutoCommit);
  }
  if (toggleAutoCommit) {
  log.debug("disabling autocommit");
  jdbcContext.connection().setAutoCommit(false);//把自动提交设为了false
  }
  } catch (SQLException e) {
  log.error("JDBC begin failed", e);
  throw new TransactionException("JDBC begin failed: ", e);
  }
  callback = jdbcContext.registerCallbackIfNecessary();
  begun = true;
  committed = false;
  rolledBack = false;
  if (timeout > 0) {
  jdbcContext.getConnectionManager().getBatcher().setTransactionTimeout(timeout);
  }
  jdbcContext.afterTransactionBegin(this);
  }

[1] [2] [3] 下一页

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训