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

时间:2018-08-17 15:08:06

标签: c# transactions persistence ignite atomicity

我正在使用Oracle数据库的Ignite.Net缓存内部的应用程序。

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

我还读到每个缓存都可以拥有自己的CacheStore,该CacheStore可以写入基础数据库,但是我还没有找到任何文档来说明我应该如何实现CacheStore类,以便数据库写入在整个Ignite事务中都是安全的。

我已经看到有关SessionEnd和CacheStoreSession(https://apacheignite-net.readme.io/v2.6/docs/persistent-store#section-sessionend-)的信息,但是这些都没有提到多个CacheStore。

以下文章说明了如何为第三方持久性处理事务,但这再次仅涉及单个Cache / CacheStore(https://www.gridgain.com/resources/blog/apache-ignite-transactions-architecture-transaction-handling-level-3rd-party) 谁能提出建议(假设确实如此),或为我提供更多示例/文档?

2 个答案:

答案 0 :(得分:1)

您尝试过吗?

我的期望是,它应该在技术上得到支持,但是由于高速缓存存储使用两阶段提交,并且多个高速缓存存储将需要使用“三阶段提交”,所以没有这样的事情-您可以预期边缘情况下的数据不一致

但是,幸福的道路应该可以正常工作。

答案 1 :(得分:1)

对于一个明确的答案(感谢您在@alamar上花费的时间),我已经与Gridgain的一位好人交谈过,可以确认可以安全地跨多个CacheStore执行事务,所有CacheStore都可以写入同一数据库而无需数据不一致。正如我所想的那样,这不是通过专门编码到Ignite中的机制来完成的,而是可以通过简单的共享数据库连接安全地实现。

要使其正常工作,您需要:

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

一个简化的代码示例:     

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();
        }
    }
}