tx

tx

spring事务其实也是切面编程。

拿到数据库连接,设置手动提交,执行sql语句,try、catch是否捕获到异常,如果捕获到就rollback,如果没有就commit,在finally中释放数据库连接

多线程下的事务提交不能使用@Transcational,需要自己手动事务操控制,拿到事务管理器,设置手动提交,利用countDownLatch来判断子线程是否执行完成,执行完成则commit,报异常则rollback

http://www.manongjc.com/detail/63-tdigaokjevyzmqr.html

 

事务的关键属性:acid,atomicity(原子性)一个事务的多个操作要么一起成功要么一起失败、

consistency(一致性)事务commit成功,数据落到磁盘有时间差,这个是保证事务的提示和数据的落库一致

isolation(隔离性)多个事务在并发执行时不会相互干扰

durability(持久性)事务对数据的修改会存储在磁盘中

事务的隔离级别

mysql默认可重复读(快照读mysql默认)、读已提交(oracle默认)、读未提交(出现脏读)、串行化(可以避免任何并发问题但是效率低下)

 

事务的传播行为

REQUIRED:将之前事物的connection传递给这个方法

REQUIRED_NEW:这个方法直接使用新的connection

 

@EnableTransactionManagement

开启事务管理功能

 

@EnableTransactionManagement会导入TransactionManagementConfigurationSelector组件返回要组成组件的全类名

①AutoProxyRegistrar给容器中注册InfrastructureAdvisorAutoProxyCreator组件,InfrastructureAdvisorAutoProxyCreator看继承关系,可以发现这个组件也是一个后置处理器,处理器创建完成后,包装对象,返回一个代理对象(增强器),代理对象执行方法,利用拦截器链执行调用。

②ProxyTransactionManagementConfiguration

1) 给容器中注册事务增强器

事务增强器需要用事务注解信息:AnnotationTransactionAttributeSource()事务拦截器:TransactionInterceptor(实现这个接口和aop的增强链一样MethodInterceptor方法拦截器):保存了事务的属性信息,事务管理器在目标方法执行的时候:执行我们的拦截器链invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {

 

 

先获取事务属性=》再获取PlatformTransactionManager(如果事先没有添加指定TransactionManager,最终会从容器中获取TransactionManager)

=》invocation.proceedWithInvocation();执行目标方法,completeTransactionAfterThrowing(txInfo, ex);如果异常获取到事务管理器,利用事务管理器回滚操作;如果正常执行commitTransactionAfterReturning(txInfo);利用事务管理器提交

 

事务不生效的原因

1、数据库引擎不支持事务

myisam

2、没有被 Spring 管理

spring没有创建代理对象

3、方法不是 public 的

spring源代码限制

4、自身调用问题

方法没有调用带有注解的,而是调用的其他未被代理的方法

5、数据源没有配置事务管理器

6、不支持事务

@Transactional(propagation = Propagation.NOT_SUPPORTED)

7、异常被吃了

8、异常类型错误

posted @ 2023-02-09 16:44  sugarstar  阅读(238)  评论(0)    收藏  举报