Spring + Hibernate Transaction - 本机SQL回滚失败

时间:2015-03-22 16:16:31

标签: sql spring hibernate

我最近遇到了这个问题 - 当我使用本机SQL时,我的事务方法(标记为@Transactional)无法执行回滚。如果我使用Hibernate API来保存实体,它确实会回滚!

  

背景

我有一个Employee()类,我有一个表tbl_employee。我想使用本机SQL向tbl_employee插入行,每次插入最多会插入500行。例如,如果我要插入600名员工,我将创建两个SQL插入查询(一个用于前500个查询,另一个用于下一个100个)。我的插入方法看起来像这样(为了简单起见,我只考虑插入(500,1000)行):

@Transactional
public void insert(List<Employee> list) throws RuntimeException{
  Dao dao = new Dao();
  String sql1 = buildSQL (list.subList(0,500));//the first 500. buildSQL is a simple method which build an insert query for the list
  String sql2 = buiildSQL (list.subList(500,list.size()));//the remaining
  dao.executeSQL(sql1);//dao performs the sql query to the database
  dao.executeSQL(sql2);
}

这是弹簧配置。我使用HibernateTransactionManager。

  <bean id="txManager"  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
         <ref local="mySessionFactory"/>
    </property>
  </bean>

我的Dao()类将我的sql执行到数据库,如果在插入过程中出现异常,我将抛出RuntimeException。

  

问题

我尝试将501名员工插入空桌。前500个具有唯一ID,最后一个具有与第一个相同的ID。因此,当我插入最后一个时,将出现“DUPLICATE PRIMARY KEY”错误。我希望前面的insert()方法将回滚 - 不应该向表中插入任何行。但是,我注意到前500个已插入数据库!

然后我尝试使用Hibernate API。我的插入方法变为:

@Transactional
public void insert(List<Employee> list) throws RuntimeException{
  Dao dao = new Dao();
  for (Employee employee: list)
     dao.save(employee);
}

它实际上做到了我的期望!一旦出现异常,就不会向数据库插入任何行。

  

我的问题

  1. 我想知道spring / hibernate是否支持本机SQL的事务管理。
  2. 如果我直接使用Hibernate“保存”一个实体,回滚就有效。我想使用本机sql的原因是我实际上需要根据插入日期时间将员工插入到不同的表中。 (例如,今年的新员工将被插入到tbl_employee_2015)。因此,使用本机SQL映射到不同的表更容易。有没有其他优雅的方法来处理映射到不同的表?
  3. 我假设一个用于多行插入的sql非常有效。因此我想通过一个sql插入500行。我不想在循环中一个接一个地保存Hibernate。这个假设是否正确?
  4. 非常感谢你的关注!

0 个答案:

没有答案