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 中的机制来完成,而是可以通过简单的共享数据库连接安全地实现。
为此,您需要:
- 使您的缓存具有事务性(AtomicityMode = CacheAtomicityMode.Transactional,WriteThrough = true)
- 在数据存储之间共享单个数据库连接(通过 CacheStoreFactory 注入或使用单例)
- 在CacheStores 的所有写入操作中,写入共享会话数据库但不提交。将会话标记为需要提交(您自己的布尔标志)。
- 在您的每个 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();
}
}
}
我正在开发一个使用 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 中的机制来完成,而是可以通过简单的共享数据库连接安全地实现。
为此,您需要:
- 使您的缓存具有事务性(AtomicityMode = CacheAtomicityMode.Transactional,WriteThrough = true)
- 在数据存储之间共享单个数据库连接(通过 CacheStoreFactory 注入或使用单例)
- 在CacheStores 的所有写入操作中,写入共享会话数据库但不提交。将会话标记为需要提交(您自己的布尔标志)。
- 在您的每个 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();
}
}
}