Apache Ignite 中事务的使用方式和机制

这段内容讲的是 Apache Ignite 中事务的使用方式和机制,包括如何启用事务、执行事务、并发模式(Concurrency Mode)和隔离级别(Isolation Level)等。下面我用中文详细解释这段内容,帮助你更好地理解。


一、事务概述(Overview)

1. 启用事务支持

要在一个缓存中使用事务,必须在配置中将缓存的 原子性模式(atomicityMode) 设置为 TRANSACTIONAL。

java 复制代码
CacheConfiguration<Integer, String> cfg = new CacheConfiguration<>("myCache");
cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
  • 只有设置为 TRANSACTIONAL 模式后,缓存才支持事务操作。
  • 如果设置为 ATOMIC(默认),则不支持事务。

🔍 参考: Atomicity Mode(原子性模式) 决定了缓存是支持原子操作(ATOMIC)还是事务操作(TRANSACTIONAL)。


二、事务的执行(Executing Transactions)

Ignite 提供了基于 Key-Value API 的事务接口,可以让你手动控制事务的开始、提交和回滚。

示例代码:

java 复制代码
Ignite ignite = Ignition.ignite();
IgniteCache<String, Integer> cache = ignite.cache("myCache");
IgniteTransactions transactions = ignite.transactions();

try (Transaction tx = transactions.txStart()) {
    Integer hello = cache.get("Hello");

    if (hello == 1)
        cache.put("Hello", 11);

    cache.put("World", 22);

    tx.commit(); // 提交事务
}

说明:

  • 使用 transactions.txStart() 启动一个事务。
  • 所有在事务中的操作(如 get、put)都会被当作一个整体。
  • 最后调用 tx.commit() 提交事务。如果发生异常,可以调用 tx.rollback() 回滚。
  • 事务是 原子性的:要么全部成功,要么全部失败,不会出现部分更新。

三、并发模式(Concurrency Modes)

事务支持两种并发模式:

并发模式 描述
OPTIMISTIC(乐观) 在事务提交时检查是否有冲突。适用于并发冲突较少的场景。
PESSIMISTIC(悲观) 在事务访问数据时立即加锁,防止其他事务修改。适用于并发冲突较多的场景。

锁的获取时机:

  • OPTIMISTIC:在事务提交时检查冲突,不提前加锁。
  • PESSIMISTIC:在事务访问数据时就加锁,直到事务提交或回滚才释放。

⚠️ 注意: 如果使用 PESSIMISTIC 模式,事务会锁定相关数据,可能会影响拓扑变更(如添加/删除节点、销毁缓存等),详见之前的"拓扑变更限制"内容。


四、隔离级别(Isolation Levels)

隔离级别决定了多个事务之间如何相互"看到"彼此的操作。

Ignite 支持以下三种隔离级别:

隔离级别 描述
READ_COMMITTED 事务只能读取已经提交的数据。防止脏读。
REPEATABLE_READ 事务在执行期间多次读取同一数据,结果保持一致。防止脏读和不可重复读。
SERIALIZABLE 最严格的隔离级别。事务串行执行,防止脏读、不可重复读和幻读。

举例说明:

  • READ_COMMITTED:你读到的数据一定是其他事务已经提交的。
  • REPEATABLE_READ:你在事务中两次读同一个 key,结果是一样的。
  • SERIALIZABLE:所有事务串行执行,不会有并发问题,但性能最低。

五、并发模式 + 隔离级别的组合

Ignite 支持所有并发模式和隔离级别的组合,每种组合有不同的行为和一致性保证。

并发模式 隔离级别 行为特点
OPTIMISTIC READ_COMMITTED 提交时检查冲突,只允许读已提交的数据
OPTIMISTIC REPEATABLE_READ 提交时检查冲突,保证事务中多次读相同数据一致
OPTIMISTIC SERIALIZABLE 提交时检查冲突,事务串行化执行
PESSIMISTIC READ_COMMITTED 访问数据时加锁,只允许读已提交的数据
PESSIMISTIC REPEATABLE_READ 访问数据时加锁,保证多次读相同数据一致
PESSIMISTIC SERIALIZABLE 访问数据时加锁,事务串行执行

六、事务配置(Transaction Configuration)

你可以在 IgniteConfiguration 中对事务进行一些全局配置,比如设置事务超时时间:

xml 复制代码
<bean class="org.apache.ignite.configuration.IgniteConfiguration">
    <property name="transactionConfiguration">
        <bean class="org.apache.ignite.configuration.TransactionConfiguration">
            <!-- 设置事务在拓扑变更时的最大等待时间为20秒 -->
            <property name="txTimeoutOnPartitionMapExchange" value="20000"/>
        </bean>
    </property>
</bean>

这个配置用于控制事务在分区映射交换(Partition Map Exchange)期间等待的最长时间。


七、总结表格

概念 说明
原子性模式 设置为 TRANSACTIONAL 才能使用事务
事务执行 使用 txStart() 开启事务,commit() 提交,rollback() 回滚
并发模式 OPTIMISTIC(乐观)和 PESSIMISTIC(悲观)
隔离级别 READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE
锁机制 PESSIMISTIC 会立即加锁,OPTIMISTIC 在提交时检查冲突
拓扑限制 PESSIMISTIC 事务期间不能修改缓存拓扑
配置 可设置事务超时时间等参数

✅ 建议做法:

  • 尽量避免长时间持有事务,尤其是 PESSIMISTIC 模式。
  • 如果并发冲突少,可以使用 OPTIMISTIC + READ_COMMITTED,性能更好。
  • 如果数据一致性要求高,可以使用 PESSIMISTIC + REPEATABLE_READ。
  • 事务中尽量减少操作的数据量和时间,避免影响集群拓扑变更。

如果你在开发中需要保证多个缓存操作的原子性和一致性,Ignite 的事务机制是一个非常有用的工具。理解并发模式和隔离级别的区别,有助于你根据业务需求选择合适的事务配置。

相关推荐
蛋蛋的就会顺顺的3 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
需要8264 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
小 黄 鸡4 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
伯恩bourne6 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
silvamux_6 小时前
curl 测试 OpenAI 兼容 API 的完整流程
java·人工智能·缓存·ai·oneapi
省钱兄--zs6 小时前
深圳24小时自助健身房软硬件解决方案实战指南与开发流程详解
java·数据仓库·spring boot·小程序·架构
顽疲7 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog7 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
用户21296835261687 小时前
开源了一个 Java 多智能体 LLM 框架 Baton:一个依赖,把 Agent 循环、工具调用、记忆、编排全配齐
java·llm
helmsail7 小时前
05 管理活动与选品
java