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、异常类型错误

浙公网安备 33010602011771号