Apache Ignite 是否提供跨多个 CacheStores 的事务?

Does Apache Ignite offer transactions across multiple CacheStores?

我正在开发一个使用 Oracle 数据库前面的 Ignite.Net 缓存的应用程序。

我了解到我可以使用 Ignite Transactions(https://apacheignite-net.readme.io/v1.5/docs/transactions#Cross-cache 个事务)一次安全地写入多个缓存。

我还读到每个缓存都可以有自己的 CacheStore 写入底层数据库,但我还没有找到任何文档来解释我应该如何实现 CacheStore 类 所以数据库写入是安全的在整个 Ignite 交易中。

我看过有关 SessionEnd 和 CacheStoreSession (https://apacheignite-net.readme.io/v2.6/docs/persistent-store#section-sessionend-) 的信息,但这些信息并未提及多个 CacheStores。

以下文章解释了如何为第 3 方持久性处理事务,但这又只讨论了单个 Cache/CacheStore (https://www.gridgain.com/resources/blog/apache-ignite-transactions-architecture-transaction-handling-level-3rd-party) 谁能告诉我这是如何工作的(假设它确实如此)或指出我进一步 examples/documentation?

你试过了吗?

我的期望,它在技术上应该得到支持,但由于缓存存储使用两阶段提交,并且多个缓存存储将需要使用 "three phase commit",并且没有这样的事情 - 你可以预期数据不一致边缘情况。

不过,快乐之路应该还行。

对于明确的答案(感谢您的时间@alamar),我已经与 Gridgain 的一位好人交谈并且可以确认可以安全地跨多个 CacheStores 执行事务,其中所有存储都写入相同的没有数据不一致的数据库。它不是像我想知道的那样通过专门编码到 Ignite 中的机制来完成,而是可以通过简单的共享数据库连接安全地实现。

为此,您需要:

  1. 使您的缓存具有事务性(AtomicityMode = CacheAtomicityMode.Transactional,WriteThrough = true)
  2. 在数据存储之间共享单个数据库连接(通过 CacheStoreFactory 注入或使用单例)
  3. 在CacheStores 的所有写入操作中,写入共享会话数据库但不提交。将会话标记为需要提交(您自己的布尔标志)。
  4. 在您的每个 CacheStores 中实施 SessionEnd (https://apacheignite-net.readme.io/docs/persistent-store#section-sessionend-)。如果尚未调用该实现,则该实现应在您的共享数据库连接上调用提交(检查之前步骤中的布尔标志并在提交后重置)。您始终可以将该逻辑封装在数据库连接中 class.

一个简化的代码示例:

public class SharedDatabaseSession
{
    private bool commitRequired;
    private DatabaseConnection databaseConnection;

    // ....

    public void Write( /*xyz*/)
    {            
        databaseConnection.Write( /*xyz*/);
        commitRequired = true;
    }

    public void Commit()
    {
        if (commitRequired)
        {
            databaseConnection.Commit();
            commitRequired = false;
        }
    }

    public static SharedDatabaseSession GetInstance()
    {
        return instance;
    }
}

public class FirstCacheStore : CacheStoreAdapter<int, int>
{
    private SharedDatabaseSession database = SharedDatabaseSession.GetInstance();

    /// ...... 

    public override void Write(int key, int val)
    {
        database.Write( /*xyz*/);
    }

    public override void SessionEnd(bool commit)
    {
        if (commit)
        {
            database.Commit();
        }
    }
}

public class SecondCacheStore : CacheStoreAdapter<int, int>
{
    private SharedDatabaseSession database = SharedDatabaseSession.GetInstance();

    /// ...... 

    public override void Write(int key, int val)
    {
        database.Write( /*xyz*/);
    }

    public override void SessionEnd(bool commit)
    {
        if (commit)
        {
            database.Commit();
        }
    }
}