seata原理图:1.3.0版本
seata主要原理在于两个代理,全局事务扫描器GlobalTransactionScanner和数据源代理SeataAutoDataSourceProxyCreator
GlobalTransactionScanner
- GlobalTransactionScanner通过继承AbstractAutoProxyCreator,代理添加了@GlobalTransactional的类,并添加到GlobalTransactionalInterceptor拦截器中;
- 当业务执行时,进入到GlobalTransactionalInterceptor的invoke方法,当被执行方法添加了@GlobalTransactional注解,则最终会进入到TransactionalTemplate;
- 在TransactionalTemplate中,开启全局事务、与TC通讯获取X_ID,执行业务方法(数据源被seata代理,则会进入代理数据源,微服务调用也会被SeataFeignClient代理,并传递事务X_ID),提交全局事务。
SeataAutoDataSourceProxyCreator
首先我们先了解下JDBC的开发流程:
// 连接数据库
Connection connection = DriverManager.getConnection(url,username,password);
// 手动事务
connection.setAutoCommit(false)
// 创建数据库操作对象
Statement statement = connection.createStatement();
// 执行sql语句,返回结果
String sql = "select * from teacher";
ResultSet resultSet = statement.executeQuery(sql);
// 提交事务
connection.commit()
- SeataAutoDataSourceProxyCreator也是通过继承AbstractAutoProxyCreator来实现代理,使用shouldSkip跳过非数据源的类,并添加到SeataAutoDataSourceProxyAdvice拦截器中;
- 当执行数据源操作时,进入SeataAutoDataSourceProxyAdvice拦截器,并将数据源转为DataSourceProxy数据源;
- DataSourceProxy获取代理连接ConnectionProxy,ConnectionProxy继承了AbstractConnectionProxy,并在AbstractConnectionProxy里重写了Statement执行器;
- 在StatementProxy执行器中通过ExecuteTemplate执行execute;
- 当execute执行到AbstractDMLBaseExecutor,在executeAutoCommitFalse方法中会将sql执行前后的镜像进行暂存;
- 最后由ConnectionProxy执行Commit,注册RM,保存日志,提交本地事务。