firstDay
参看上一篇
具体实现
使用二阶段模式
使用AOP代理数据源
写一个Coordinator单独出来,使用RPC协议远程协调
HTTP拦截器传递全局事务上下文
完成上述的实现即可 包含的东西不少 有远程协议netty 还有spring 主要核心点在这两个大选手上面
2pc来实现
netty
首先需要一个网络通讯框架。因为只是内部AP TM RM使用所以不会使用http这种七层协议。Java端肯定首选netty这个框架
不会用netty的同学去学一下:
在基于阅读的同学已经学会netty的情况下
大体实现逻辑:定义一个netty-server netty-client 编解码实现类 具体的就不贴了 都是很容易实现的代码
tm-service
第一天写了如果需要使用2pc 则内部需包含TM(事务管理器) RM(资源管理) AP(application)
使用AOP代理数据源
1 需要使用到自定义数据库连接代理类(毕竟jdk自带的不满足自己的需求) 所以我们需要自定义一个实现Java的java.sql.Connection接口的实现类
@Setter
private boolean isFinished = true;
@Override
public void commit() throws SQLException {
log.info("Connection:{} 进行提交操作",this);
if(isFinished) {
connection.commit();
}
if(!this.isClosed()){
this.close();
}
}
@Override
public void rollback() throws SQLException {
log.info("Connection:{} 进行回滚操作",this);
if(isFinished) {
connection.rollback();
}
if(!this.isClosed()){
this.close();
}
}
@Override
public void close() throws SQLException {
if(isFinished){
log.info("无全局事务或全局事务处于完成完成状态,可以关闭数据库连接");
log.info("Connection:{} 已关闭",this);
connection.close();
}else{
log.info("全局事务存在且未完成,不关闭数据库连接");
log.info("Connection:{} 未关闭",this);
}
}
public ConnectionProxy(Connection connection) {
super(connection);
}
2 需要一个切面用来替换掉原先的connect的东西
/**
* 代理数据源,替换得到的Connection为自定义的代理类
*/
@Around("execution(* javax.sql.DataSource.getConnection(..))")
public Connection around(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("数据库连接切面环绕切入前....");
Connection connection = (Connection)joinPoint.proceed();
ConnectionProxy myConnection = new ConnectionProxy(connection);
if(GlobalTransactionManager.getGroupId() != null){
log.info("发现全局事务,禁用自动提交");
myConnection.setAutoCommit(false);
myConnection.setFinished(false);
//设置事务隔离级别为:读未提交
myConnection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
GlobalTransactionManager.addConnection(myConnection);
}
log.info("数据库连接切面环绕切入后....");
return myConnection;
}