Seata 1.5.2 源码学习( 三 )


6、GlobalTransactionScanner#wrapIfNecessary()中创建了一个GlobalTransactionalInterceptor,GlobalTransactionalInterceptor是一个MethodInterceptor
7、在创建代理对象的时候 , 在AbstractAutoProxyCreator#wrapIfNecessary()方法中,为代理对象应用GlobalTransactionalInterceptor,于是所有目标对象上的方法调用就会转为调用GlobalTransactionalInterceptor#invoke()
8、GlobalTransactionalInterceptor#invoke()方法中,首先获取被调用的目标对象的Class和Method对象,然后检查目标方法或类上是否有@GlobalTransactional或@GlobalLock注解,而且配置项中不能禁用全局事务
9、如果加了@GlobalTransactional注解 , 则创建一个AspectTransactional,然后开始处理全局事务,默认传播特性是REQUIRED
10、如果加了@GlobalLock注解 , 则开始处理全局锁
11、处理全局事务就是直接调用事务模板中的execute方法,TransactionalTemplate#execute()是一个模板方法,其中定义了事务处理的流程 。首先开启事务 , 然后执行业务逻辑,最后提交事务 , 异常回滚事务 。
12、事务操作是在DefaultGlobalTransaction中处理的,最终处理在DefaultTransactionManager 。DefaultTransactionManager负责同步远程调用,向TC发请求来开启、提交、回滚事务等操作

Seata 1.5.2 源码学习

文章插图
3. 数据库操作执行SQL语句
通过Java自带的JDBC操作数据库通常是这样的:
Class.forName(driverClass);// 获取ConnectionConnection connection = DriverManager.getConnection(url,user,password);// 创建Statement或者PreparedStatementStatement stmt = connection.createStatement();stmt.execute(sql);// PreparedStatement ps = connection.prepareStatement(sql);// ps.execute();MyBatis底层也是这一套
接下来看Seata是如何做的
首先是获取数据库连接Connection,前面已经说过了,调用DataSource的getConnection()方法底层是在代理对象SeataDataSourceProxy上调用getConnection() 。SeataDataSourceProxy是接口,如果是AT模式 , 则这个数据源代理对象是DataSourceProxy
Seata 1.5.2 源码学习

文章插图

Seata 1.5.2 源码学习

文章插图
DataSourceProxy#getConnection()获取数据库连接
Seata 1.5.2 源码学习

文章插图

Seata 1.5.2 源码学习

文章插图
ConnectionProxy#createStatement()
Seata 1.5.2 源码学习

文章插图

Seata 1.5.2 源码学习

文章插图

Seata 1.5.2 源码学习

文章插图

Seata 1.5.2 源码学习

文章插图
ConnectionProxy#prepareStatement()
【Seata 1.5.2 源码学习】
Seata 1.5.2 源码学习

文章插图

Seata 1.5.2 源码学习

文章插图
PreparedStatementProxy 继承自 StatementProxy,因此下面就直接看PreparedStatementProxy如何执行SQL
PreparedStatementProxy#execute()
Seata 1.5.2 源码学习

文章插图
ExecuteTemplate#execute()  是一个模板方法
Seata 1.5.2 源码学习

文章插图
挑一个看看吧 , 就挑UpdateExecutor
Seata 1.5.2 源码学习

文章插图

Seata 1.5.2 源码学习

文章插图

Seata 1.5.2 源码学习

文章插图
UpdateExecutor构造方法中一直调父类的构造法 , 既然如此,那么直接看BaseTransactionalExecutor
Seata 1.5.2 源码学习

文章插图
UpdateExecutor#execute()
这个方法时从BaseTransactionalExecutor那里继承来的 , 又是一个模板方法,可见设计模式是多么重要
Seata 1.5.2 源码学习

文章插图
AbstractDMLBaseExecutor#doExecute()
Seata 1.5.2 源码学习

文章插图
AbstractDMLBaseExecutor#executeAutoCommitTrue()
Seata 1.5.2 源码学习

文章插图

推荐阅读