事务
1、事务就是指准备要做的或所做的事情,在计算机语言中是指访问并可能更新数据库中各种数据项的一个程序单元,也是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。
2、提交事务:Commit Transaction,成功的结束,将所有的DML语句操作历史记录和底层硬盘数据来一次同步
3、事务回滚:End Transaction,失败的结束,将所有的DML(insert、update、delete)语句操作历史记录全部清空。
所谓回滚事务,简单来说就是当一个事务的某一个操作发生问题时,整个事务可以回滚掉,就像没有做任何操作一样,换言之当发生错误或事务被取消,则回滚事务。
当开启事务之后,所有的操作都会被存储在事务日志中,而只有当我们进行提交事务的操作后,才会将我们更新的数据同步到数据表中。
事务控制的方式
编程式事务:就是直接在代码里手动开启事务,手动提交,手动回滚。优点就是可以灵活控制,缺点就是太麻烦了,太多重复的代码了。
声明式事务:就是使用SpringAop配置事务,这种方式大大的简化了编码。需要注意的是切入点表达式一定要写正确。
#声明式事务需要在配置里面添加一下配置
<tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
注解事务:直接在Service层的方法上面加上@Transactional注解;
@Transactional可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。
常见到的3种事务不回滚的产生原因:
(1)声明式事务配置切入点表达式写错了,没切中Service中的方法
(2)Service方法中,把异常给try catch了,但catch里面只是打印了异常信息,没有手动抛出RuntimeException异常
(3)Service方法中,抛出的异常不属于运行时异常(如IO异常),因为Spring默认情况下是捕获到运行时异常就回滚
实例
1.简单开启事务管理
@EnableTransactionManagement // 启注解事务管理,等同于xml配置方式的 <tx:annotation-driven />
没有在程序中手动捕获异常
@Transactional(rollbackOn = { Exception.class }) //事务回滚
public void test() throws Exception {
doStuff1();
doStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doStuff1()对数据库的操作 会回滚。
}
程序中自己捕获异常
@Transactional(rollbackOn = { Exception.class })
public void test() {
try {
doStuff1();
doStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doStuff1()对数据库的操作 不会回滚。
} catch (Exception e) {
e.printStackTrace();
}
}
需要手动抛出异常
@Transactional(rollbackOn = { Exception.class })
public void test() {
try {
doStuff1();
doStuff2();
} catch (Exception e) {
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//加上之后,如果doStuff2()抛了异常,
//doStuff1()是会回滚的
}
}