spring 事务:
一: 理论:
事务(ACID):
A:原子性-都成功,都失败;
C:一致性(A转账给B,A扣了一百,B的钱一定增加);
I:隔离性(事务之间互不干扰);
D:持久性(修改是永久的)
1. 传播行为: 一个事务掉另一个事务,多个事务操作时怎么处理
1.1 PROPAGATION_REQUIRED(默认): 当前事务存在,使用当前事务;当前不存在, 新建一个事务
1.2 PROPAGATION_SUPPORTS: 当前事务存在,使用当前事务;当前不存在, 则不建立事务, 用非事务方式执行
1.3 PROPAGATION_MANDATORY: 当前事务存在,使用当前事务;当前不存在,抛异常
1.4 PROPAGATION_REQUIRES_NEW: 当前事务存在则挂起, 新建一个事务, 两个事务独立运行,可通过捕获新建事务执行异常判断当前事务是否需要回滚操作
1.5 PROPAGATION_NOT_SUPPORTED: 当前事务存在则挂起,用非事务方式执行
1.6 PROPAGATION_NEVER: 当前事务存在则抛异常,用非事务方式执行
1.7 PROPAGATION_NESTED: 当前事务存在则嵌套事务, 不存在则新建一个事务
@Transactional(propagation=Propagation.PROPAGATION_REQUIRED)
2. 隔离级别:
并发情况会出现:
脏读: 读取未提交数据
不可重复读: 读取过程中有数据更新
幻读: 修改过程中, 有数据更新
2.1 ISOLATION_DEFAULT 默认级别
2.2 ISOLATION_READ_UNCOMMITTED: 读未提交的数据
2.3 ISOLATION_READ_COMMITTED: 读已提交数据
2.4 ISOLATION_REPEATABLE_READ(默认): 多次读取结果一致
2.5 ISOLATION_SERIALIZABLE: 锁表,一个一个来
@Transactional(isolation = Isolation.READ_COMMITTED)
@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
3. 回滚:
默认: RuntimeException和Error
@Transactional(rollbackFor=Exception.class): 让在发生非RuntimeException时也能回滚
@Transactional(rollbackFor={RuntimeException.class, Exception.class}: 多个
@Transactional(rollbackForClassName={“RuntimeException”,“Exception”}): 多个
@Transactional(notRollbackFor=Exception.class): 让在发生RuntimeException时不回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); // 手动回滚事务
4. 超时: 超时则回滚
@Transactional(timeout = 1000)
5. 是否只读:
@Transactional(readOnly = true): 只查询, 不修改
二: 应用:
1. xml式: 略
2. transactional
2.1 原理: spring通过aop动态代理生成bean容器里面的实例,当遇到@transactional注解的类, 会生成代理类继承原来那个bean,
通过代理类调用方法才会使@transactional生效,创建事务;
2.1 失效原因: 1. 本类方法调用, 方法a内部调用方法b, 类似于this.b, 必须经过代理类调用才会生效, 例如, B.b();
SpringContextHolder.getBean(B.class): 获取容器中B类的实例(有@transactional注解的是代理类);
2. 因为aop代理的原因, 方法必须是实现的public方法, 其他比如private, aop拿不到, 注解也就失效了
默认传播行为前提下:
方法a调用方法b, spring 先看a有没有事务, 然后再看b有没有事务
1. a 没有事务, a,b 都不会有事务
2. a 有事务, b有事务, 遵循传播行为, a,b共用a的事务
3. a 有事务, b没有事务, 遵循传播行为, a有事务,b没有事务



