问题发生场景: 这是前段时间去面试的时候被问到的一道题,当时答不上来, 回来想想觉得挺有趣的,所以就写一段代码测试一下
问题描述:在需要事务的方法内,try catch捕捉异常后,spring还能回滚事务吗?
答:可以回滚,也可以不会滚 详情往下看
解决方案:本测试用例我用的hibernate3+spring3+junit, hibernate和spring全部使用注解的方式
spring配置事务(部分关键代码):
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
hibernate的配置就不贴上来了
代码:
因为dao里面没有写任何代码,service接口等代码我就不贴出来了,只贴实体类的代码,其他的贴截图
1.实体类TestPo.java
package test.trasional.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name="tbl_TestPo")
public class TestPo implements Serializable
{
private static final long serialVersionUID = 1L;
private String id;
private String name;
private int age;
private String province;
@GenericGenerator(name = "generator", strategy = "uuid.hex")
@Id
@GeneratedValue(generator = "generator")
@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = true, length = 32)
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
@Column(name = "name")
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Column(name = "age")
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
@Column(name = "province")
public String getProvince()
{
return province;
}
public void setProvince(String province)
{
this.province = province;
}
}
下面开始测试
测试类:
捕捉异常
事务执行
由异常结果可以看出,在方法里面捕捉异常后,导致事务失效,不能回滚,导致数据持久化到了数据库
问题原因:因为报出异常后,我没有在catch里面使用throw抛出异常,所以就相当于在catch里面处理了异常,所以spring当然捕捉不到异常
下面是正确的处理方法:
在catch里面使用 throw 抛出指定的异常,或者抛出 RuntimeException,除非程序报的是Exception异常,否则不能抛出Excption,否则会导致事务失效
本次测试结束.