9. sharding-jdbc源码之最大努力型事务

本文主要探讨了sharding-jdbc中的最大努力送达型事务,适用于幂等性的数据库操作。介绍了事务架构图、适用场景和限制,并详细分析了事务日志存储器、事务监听器和异步送达JOB任务的核心源码。通过事务日志存储接口、柔性事务管理器和异步执行的流程,揭示了sharding-jdbc如何实现最大努力送达型事务。
摘要由CSDN通过智能技术生成

阿飞Javaer,转载请注明原创出处,谢谢!

BASE Transaction

  • Best efforts delivery transaction (已经实现).
  • Try confirm cancel transaction (待定).

Sharding-JDBC由于性能方面的考量,决定不支持强一致性分布式事务。

最大努力送达型事务

在分布式数据库的场景下,相信对于该数据库的操作最终一定可以成功,所以通过最大努力反复尝试送达操作。

最大努力送达型事务的架构图

最大努力送达型事务的架构图

摘自sharding-jdbc使用指南☞事务支持

执行过程有以下几种情况:
1. 执行成功–如图所示,执行结果事件->监听执行事件->执行成功->清理事务日志
2. 执行失败,同步重试成功–如图所示,执行结果事件->监听执行事件->执行失败->重试执行->执行成功->清理事务日志
3. 执行失败,同步重试失败,异步重试成功–如图所示,执行结果事件->监听执行事件->执行失败->重试执行->执行失败->”异步送达作业”重试执行->执行成功->清理事务日志
4. 执行失败,同步重试失败,异步重试失败,事务日志保留—-如图所示,执行结果事件->监听执行事件->执行失败->重试执行->执行失败->”异步送达作业”重试执行->执行失败->… …

说明:不管执行结果如何,执行前事件都会记录事务日志;执行事件类型包括3种:BEFORE_EXECUTEEXECUTE_FAILUREEXECUTE_SUCCESS;另外,这里的”同步“不是绝对的同步执行,而是通过google-guava的EventBus发布事件后,在监听端判断是EXECUTE_FAILURE事件,最多重试syncMaxDeliveryTryTimes次;后面对BestEffortsDeliveryListener的源码分析有介绍;这里的”异步“通过外挂实现,在后面的文章10. sharding-jdbc源码之异步送达JOB会有分析;

适用场景

  • 根据主键删除数据。
  • 更新记录永久状态,如更新通知送达状态。

使用限制

  • 使用最大努力送达型柔性事务的SQL需要满足幂等性。
  • INSERT语句要求必须包含主键,且不能是自增主键。
  • UPDATE语句要求幂等,不能是UPDATE xxx SET x=x+1
  • DELETE语句无要求。

开发示例

// 1. 配置SoftTransactionConfiguration
SoftTransactionConfiguration transactionConfig = new SoftTransactionConfiguration(dataSource);
// 配置相关请看后面的备注
transactionConfig.setXXX();

// 2. 初始化SoftTransactionManager
SoftTransactionManager transactionManager = new SoftTransactionManager(transactionConfig);
transactionManager.init();

// 3. 获取BEDSoftTransaction
BEDSoftTransaction transaction = (BEDSoftTransaction) transactionManager.getTransaction(SoftTransactionType.BestEffortsDelivery);

// 4. 开启事务
transaction.begin(connection);

// 5. 执行JDBC
/* 
    code here
*/
* 
// 6.关闭事务
transaction.end();

备注:SoftTransactionConfiguration支持的配置以及含义请参考sharding-jdbc使用指南☞事务支持,这段开发示例的代码也摘自这里;也可参考sharding-jdbc-transaction模块中com.dangdang.ddframe.rdb.transaction.soft.integrate.SoftTransactionTest如何使用柔性事务,但是这里的代码需要稍作修改,否则只是普通的执行逻辑,不是sharding-jdbc的执行逻辑

@Test
public void bedSoftTransactionTest() throws SQLException {
    SoftTransactionManager transactionManagerFactory = new SoftTransactionManager(getSoftTransactionConfiguration(getShardingDataSource()));
    // 初始化柔性事务管理器
    transactionManagerFactory.init();
    BEDSoftTransaction transactionManager = (BEDSoftTransaction) transactionManagerFactory.getTransaction(SoftTransactionType.BestEffortsDelivery);
    transactionManager.begin(getShardingDataSource().getConnection());
    // 执行INSERT SQL(DML类型),如果执行过程中异常,会在`BestEffortsDeliveryListener`中重试
    insert();
    transactionManager.end();
}

private void insert() {
    String dbSchema = "insert into transaction_test(id, remark) values (2, ?)";
    try (
            // 将.getConnection("db_trans", SQLType.DML)移除,这样的话,得到的才是ShardingConnection 
            Connection conn = getShardingDataSource().getConnection();
            PreparedStatement preparedStatement = conn.prepareStatement(dbSchema)) {
        preparedStatement.setString(1
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值