假设我有一些像这样的标准NHibernate代码,它写入SQL数据库:
using (var session = SessionFactory.OpenSession())
{
using (var tx = session.BeginTransaction())
{
var customer = session.Get<Customer>(id);
customer.Property1 = "new value";
customer.Property2 = "new value";
tx.Commit();
}
}
我正在尝试为Customer创建一个副本表(在NoSQL数据库中)。因此,当上面的代码运行时,运行以下事件处理程序:
public void OnPostUpdate(PostUpdateEvent postUpdateEvent)
{
if (postDeleteEvent.Entity.GetType() == typeof(Customer))
{
var customer = (Customer)postUpdateEvent.Entity;
customerCopyRepository.Update(customer);
}
}
如果我要将第一个代码片段更改为插入,那么这将运行:
public void OnPostInsert(PostInsertEvent postInsertEvent)
{
if (postInsertEvent.Entity.GetType() == typeof(Customer))
{
var customer = (Customer)postInsertEvent.Entity;
customerCopyRepository.Insert(customer);
}
}
当发生删除时,运行:
public void OnPostDelete(PostDeleteEvent postDeleteEvent)
{
if (postDeleteEvent.Entity.GetType() == typeof(Customer))
{
var customer = (Customer)postDeleteEvent.Entity;
customerCopyRepository.Delete(customer.Id);
}
}
将CustomerCopyRepository注入到类构造函数中。
这非常好用。我唯一的问题是上面的每个事件似乎都在数据提交到数据库之前运行。因此,可能会出现以下情况:
1)将客户写入NoSQL数据库。
2)客户未写入SQL数据库(因为SQL错误)。
有什么方法可以阻止这种情况吗?
答案 0 :(得分:0)
我有完全相同的场景(与ElasticSearch同步),最后我使用了RegisterSynchronization方法:
private void Sync(IPostDatabaseOperationEventArgs e)
{
e.Session.Transaction.RegisterSynchronization(new AfterTransactionCompletes(success =>
{
if (!success)
return;
// Do your stuff
}));
}