微服务架构中,事务的统一性是一个重要的问题。程序员需要简洁有效地控制事务。JMSFramework 的诞生旨在提供更简单、更有效的事务控制方案。
先看一段客户端调用微服务的代码:
using (var rc = new RemoteClient())
{
//启动分布式事务
rc.BeginTransaction();
//调用用户信息微服务,创建新用户
var uis = rc.GetMicroService<UserInfoService>();
var userid = uis.CreateUser();
//调用银行微服务,创建用户的银行账号
var bks = tran.GetMicroService<BankService>();
bks.CreateBankAccount( userid );
//提交分布式事务
rc.CommitTransaction();
}
在该段代码中,我们分别调用了两个不同的微服务进行业务操作。最后,通过 CommitTransaction 方法,统一提交这两个微服务的事务。
值得注意的是,由于 rc 对象被包裹在 using 中,所以即使其中任意一行代码发生异常也会触发整体事务回滚。
这种简洁且符合编程习惯的代码风格,值得借鉴。
我们再看一下微服务端的代码:
UserInfoService:
public int CreateUser()
{
var dbContext = new UserInfoDBContext();
dbContext.BeginTransaction(); //启动事务
//编写业务代码
.........
//最后无需提交事务,由框架底层自动控制
return newUserId;
}
BankService:
public int CreateBankAccount(int userid)
{
var dbContext = new BankDBContext();
dbContext.BeginTransaction(); //启动事务
//...编写创建银行账户的业务代码
return userBankId;
}
服务端代码无需编写任何分布式事务的代码,只需启动事务即可,对繁琐的事务处理说再见,让开发人员从中解放。
事务实现原理
应用层
1、应用层调用微服务,微服务返回调用结果,并告知应用层,微服务端是否有事务放在委托当中。
2、当应用层继续调用其他微服务的时候,如果发生异常,通知所有微服务的委托回滚事务;
3、如果没有发生异常,全部微服务调用完毕,先确认一下所有调用的微服务器是否还正常响应,任何一个服务器响应不正常,也通知所有服务器的远程委托回滚事务;
4、如果所有服务器响应正常,通知网关把事务标记为成功,并通知远程委托提交事务。
微服务端
1、接到应用层指令,执行完函数,返回结果给应用层,然后继续和应用层保持长连接,保持心跳。
2、如果一切正常,最后响应应用层的指令,提交/回滚事务。
3、如果连接意外断开,咨询网关事务是否已成功,如果网关回答说成功,则提交事务,反之,回滚事务。
4、如果微服务宕机,下次重启后读取未提交的事务,并咨询网关事务是否已成功,如果网关回答说成功,则重新执行操作+提交事务。