Sharding-JDBC-分布式事务

分布式事务

1. 两阶段提交-XA

1.1 引入Maven依赖

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-transaction-xa-core</artifactId>
    <version>${shardingsphere.version}</version>
</dependency>

XA事务管理器将以SPI的方式被Sharding-JDBC所加载。

1.2 Atomikos参数配置 (可选)

ShardingSphere默认的XA事务管理器为Atomikos,在项目的logs目录中会生成xa_tx.log, 这是XA崩溃恢复时所需的日志,请勿删除。

也可以通过在项目的classpath中添加jta.properties来定制化Atomikos配置项。具体的配置规则请参考Atomikos的官方文档

2. 第三方BASE实现-Saga

目前Apache/incubator-shardingsphere暂无BASE事务的实现,但是仍然可以使用第三方实现的Saga事务。

项目地址: shardingsphere-spi-impl

文中涉及${shardingsphere-spi-impl.version} 的jar暂未发布到maven中央仓,因此需要您根据源码自行部署。

2.1 引入Maven依赖

<dependency>
    <groupId>io.shardingsphere</groupId>
    <artifactId>sharding-transaction-base-saga</artifactId>
    <version>${shardingsphere-spi-impl.version}</version>
</dependency>

Saga事务管理器将以SPI的方式被Sharding-JDBC所加载。

2.2 Saga相关配置

可以通过在项目的classpath中添加saga.properties来定制化Saga事务的配置项。 配置项的属性及说明如下:

属性名称 默认值 说明
saga.actuator.executor.size 5 Saga引擎所使用的线程池大小
saga.actuator.transaction.max.retries 5 Saga引擎对失败SQL的最大重试次数
saga.actuator.compensation.max.retries 5 Saga引擎对失败SQL的最大尝试补偿次数
saga.actuator.transaction.retry.delay.milliseconds 5000 Saga引擎对失败SQL的重试间隔,单位毫秒
saga.actuator.compensation.retry.delay.milliseconds 3000 Saga引擎对失败SQL的补偿间隔,单位毫秒
saga.persistence.enabled false Saga引擎对快照及执行日志进行持久化
saga.actuator.recovery.policy ForwardRecovery Saga引擎对失败事务的补偿策略,ForwardRecovery为最大努力送达,BackwardRecovery为反向SQL补偿

2.3 Saga 快照及日志持久化

saga.persistence.enabled设置为true时,Saga引擎将会对事务的快照及执行日志进行持久化操作。 持久化操作默认通过HikariCP链接池写入到MySQL、H2或PostgreSQL数据库中。 关于持久化的配置,同样添加在saga.properties中,配置项及说明如下:

属性名称 默认值 说明
saga.persistence.ds.url Saga持久化的数据库JDBC链接
saga.persistence.ds.username Saga持久化的数据库用户名
saga.persistence.ds.password Saga持久化的数据库密码
saga.persistence.ds.max.pool.size 50 Saga持久化的数据库链接池最大连接数
saga.persistence.ds.min.pool.size 1 Saga持久化的数据库链接池最小连接数
saga.persistence.ds.max.life.time.milliseconds 0(无限制) Saga持久化的数据库链接最大存活时间,单位毫秒
saga.persistence.ds.idle.timeout.milliseconds 60 * 1000 Saga持久化的数据库链接空闲回收时间,单位毫秒
saga.persistence.ds.connection.timeout.milliseconds 30 * 1000 Saga持久化的数据库链接超时时间,单位毫秒

由于用户使用的数据库类型与事务大小不一定一致,因此可以在项目的classpath中添加schema-init.sql来定制化持久化的表结构,Saga引擎会自动根据其中SQL创建。 如下以MySQL为例,用户可自行修改,以匹配不同数据库类型及字段长度。

-- MySQL init table SQL

CREATE TABLE IF NOT EXISTS saga_snapshot(
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  transaction_id VARCHAR(255) null,
  snapshot_id int null,
  revert_context VARCHAR(255) null,
  transaction_context VARCHAR(255) null,
  create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  INDEX transaction_snapshot_index(transaction_id, snapshot_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS saga_event(
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  saga_id VARCHAR(255) null,
  type VARCHAR(255) null,
  content_json TEXT null,
  create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  INDEX saga_id_index(saga_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8

2.4 Saga 快照及日志持久化SPI定制

默认通过数据库来持久化快照和日志并不一定能够满足用户对业务和性能的需求。因此Saga引擎提供SPI允许用户定制化持久化部分。 当saga.persistence.enabled设置为true且Saga引擎监测到有持久化SPI时,Saga引擎将通过用户实现的SPI代替默认持久化进行持久化工作。 用户只需要实现接口io.shardingsphere.transaction.saga.persistence.SagaPersistence即可实现持久化SPI。 具体可参考项目sharding-transaction-base-saga-persistence-jpa,Maven引入:

<dependency>
    <groupId>io.shardingsphere</groupId>
    <artifactId>sharding-transaction-base-saga-persistence-jpa</artifactId>
    <version>${shardingsphere-spi-impl.version}</version>
</dependency>

2.5 Saga 注意事项

  • 反向SQL需要主键,请确保在表结构中定义主键
  • 对于INSERT语句, 需要在SQL中显示插入主键值,如INSERT INTO ${table_name} (id, value, ...) VALUES (11111, '', ....) (其中id为表主键)
  • 若需要自动生成主键,可使用ShardingSphere的分布式主键(分布式主键不能为联合主键)。

3. 分布式事务接入端

ShardingSphere的事务类型存放在TransactionTypeHolder的本地线程变量中,因此在数据库连接创建前修改此值,可以达到自由切换事务类型的效果。

注意:数据库连接创建之后,事务类型将无法更改。

3.1 原生API

TransactionTypeHolder.set(TransactionType.LOCAL);

 TransactionTypeHolder.set(TransactionType.XA);

TransactionTypeHolder.set(TransactionType.BASE);

3.2 Spring注解

@ShardingTransactionType(TransactionType.LOCAL)
@Transactional

@ShardingTransactionType(TransactionType.XA)
@Transactional

@ShardingTransactionType(TransactionType.BASE)
@Transactional

注意:@ShardingTransactionType需要同Spring的@Transactional配套使用,事务才会生效。

Spring boot starter

引入Maven依赖:

<dependency>
    <groupId>io.shardingsphere</groupId>
    <artifactId>sharding-transaction-jdbc-spring-boot-starter</artifactId>
    <version>${shardingsphere-spi-impl.version}</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>${aspectjweaver.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${springframework.version}</version>
</dependency>

<aspectjweaver.version>1.8.9</aspectjweaver.version>
<springframework.version>[4.3.6.RELEASE,5.0.0.M1)</springframework.version>

Spring namespace

引入Maven依赖:

<dependency>
    <groupId>io.shardingsphere</groupId>
    <artifactId>sharding-transaction-jdbc-spring</artifactId>
    <version>${shardingsphere-spi-impl.version}</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>${aspectjweaver.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${springframework.version}</version>
</dependency>

<aspectjweaver.version>1.8.9</aspectjweaver.version>
<springframework.version>[4.3.6.RELEASE,5.0.0.M1)</springframework.version>

加载切面配置信息

<import resource="classpath:META-INF/shardingTransaction.xml"/>

分布式事务example

transaction-example

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355

推荐阅读更多精彩内容

  • 1 Saga相关概念 1987年普林斯顿大学的Hector Garcia-Molina和Kenneth Salem...
    shoukai阅读 88,254评论 4 65
  • 原文链接:https://docs.spring.io/spring-boot/docs/1.4.x/refere...
    pseudo_niaonao阅读 4,702评论 0 9
  • 再有人问你分布式事务,把这篇扔给他 咖啡拿铁纯洁的微笑今天 前言 不知道你是否遇到过这样的情况,去小卖铺买东西,付...
    冬_2bf6阅读 609评论 0 0
  • 我在最美的时节思念着你 夏日的萤火虫 微小的光芒 照亮了唐诗宋词泛黄的手卷 石碑上有古老的秘密在流传 青竹染香 鸿...
    心一Sue阅读 390评论 3 10
  • 生活中处处充满惊喜。 我的人生也是。 因为我就要死了,在我20岁生日那天。 取出盒中最后一支烟,点燃,深深吸了一口...
    张颈鹿的故事阅读 196评论 0 0