事务简单介绍和事物失效
数据库事务失效
数据库事务(Database Transaction):将有限系列的执行命令作为单个逻辑执行单元,单元内的任务要么全部 成功,要么全部失败。数据库事务拥有四大特性,通常称为ACID,具体说明如下
- 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行
- 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束
- 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行
- 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中
spring的注解@Transactional使用也存在一些限制和注意的问题还是来看看具体的例子,看看到底是什么原因导致事务失效呢?
1. 无事务
方法不加注解抛异常,执行有异常抛出,z1表成功新增一条记录
1 | public void testTransaction() { |
2.有事务且是同一个方法
方法加注解抛异常,执行有异常抛出,z1、z2表都没有新增记录,事务正常
1 |
|
3.有事务且事务仅在第一个方法上
方法加注解并调用该类其他方法并抛异常,执行有异常抛出,z1、z2表无新增记录
1 |
|
4.有事务事务在被调用者上,本地方法调用
调用含注解的方法并抛异常,执行有异常抛出,z1表新增记录、z2表无新增记录,事务失效
1 | public void testTransaction() { |
为什么事务会失效呢?关于这一点Spring Transactional官方说明如下:
- 在代理下(默认或当配置为proxy-target-class=”true”),只有当前代理类的外部方法调用注解方法时代理才会被拦截。事实上,这意味着:一个目标对象的方法调用该目标对象的另外一个方法,即使被调用的方法已使用了@Transactional注解标记,事务也不会有效执行。
- AOP使用的是动态代理的机制,它会给类生成一个代理类,注解相关操作都在代理类上完成。内部方式使用this或者直接调用时,使用的是实例调用,并没有通过代理类调用方法,所以会导致注解失效。
- @Transactional注解只对代理类时的public方法有效,被protected、private、package-visible修饰的方法使用@Transactional注解无效
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Chenghao-blog!




