我最近遇到了这个问题 - 当我使用本机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);
}
它实际上做到了我的期望!一旦出现异常,就不会向数据库插入任何行。
我的问题
非常感谢你的关注!