JCache是否支持EJB事务下缓存读写?事务回滚需清理缓存
Great question! Let's break this down clearly for you:
Short answer: Yes, JCache (JSR-107) natively supports integration with JTA transactions, and Redisson's JCache implementation fully handles cache reads/writes within EJB transactions—including automatically rolling back any cache entries added/modified during a failed transaction.
1. JCache's Transactional Foundation
The JCache spec defines three transaction modes, and the ones relevant for EJB are:
LOCAL: For single-cache-instance transactions (works well with a standalone Redis node)XA: For distributed XA transactions (ideal if you're working with Redis clusters or need to coordinate cache operations with other transactional resources like databases)
EJB's Container-Managed Transactions (CMT, the default) or Bean-Managed Transactions (BMT) will seamlessly bind cache operations to the current transaction context when you configure the right mode.
2. How Redisson Handles Transaction Rollbacks
When you perform cache operations like put() or remove() inside an EJB transaction method, Redisson doesn't immediately apply these changes to Redis. Instead:
- It stages all modifications in a transactional buffer tied to your EJB transaction
- If the transaction commits, all staged changes are persisted to Redis
- If the transaction rolls back, Redisson automatically undoes every cache change from that transaction—this includes deleting any entries you added, and restoring any existing entries you modified during the transaction.
3. Key Configuration Steps
To enable this behavior, you need to turn on transaction support in your Redisson JCache setup:
Option 1: YAML Configuration (redisson-jcache.yaml)
cacheConfigs: yourCacheName: transactionMode: XA # Use LOCAL if you're on a single Redis node
Option 2: Programmatic Configuration
// Create a mutable config for your cache MutableConfiguration<String, Object> cacheConfig = new MutableConfiguration<>(); cacheConfig.setTransactionEnabled(true); cacheConfig.setTransactionMode(TransactionMode.XA); // Or LOCAL // Initialize the cache with transaction support CacheManager cacheManager = Caching.getCachingProvider().getCacheManager(); Cache<String, Object> yourCache = cacheManager.createCache("yourCacheName", cacheConfig);
4. Quick Notes to Avoid Pitfalls
- Make sure your EJB is using JTA transactions (CMT is enabled by default for EJBs, so this is usually a given)
- For Redis clusters, stick with
XAmode to ensure cross-node transaction consistency - Reads within the same transaction are transaction-aware: you'll see the modified cache values from the current transaction, not the ones persisted in Redis, which keeps your transaction state consistent.
内容的提问来源于stack exchange,提问作者Ismail Sahin

