问题
Say I have some standard NHibernate code like this, which writes to an SQL database:
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();
}
}
I am trying to create a copy table for the Customer (in a NoSQL database). Therefore when the code above runs the following event handler runs:
public void OnPostUpdate(PostUpdateEvent postUpdateEvent)
{
if (postDeleteEvent.Entity.GetType() == typeof(Customer))
{
var customer = (Customer)postUpdateEvent.Entity;
customerCopyRepository.Update(customer);
}
}
If I was to change the first code fragment to an insert, then this would run:
public void OnPostInsert(PostInsertEvent postInsertEvent)
{
if (postInsertEvent.Entity.GetType() == typeof(Customer))
{
var customer = (Customer)postInsertEvent.Entity;
customerCopyRepository.Insert(customer);
}
}
and when a delete occurs this runs:
public void OnPostDelete(PostDeleteEvent postDeleteEvent)
{
if (postDeleteEvent.Entity.GetType() == typeof(Customer))
{
var customer = (Customer)postDeleteEvent.Entity;
customerCopyRepository.Delete(customer.Id);
}
}
CustomerCopyRepository is injected into the class constructor.
This is working very nicely. The only problem I have is that each of the events above seem to run before the data is committed to the database. Therefore the following scenario could occur:
1) Write Customer to NoSQL database.
2) Customer is not written to SQL database(because of an SQL error).
Is there any way I can prevent this scenario?
回答1:
I have exactly the same scenario (Sync with ElasticSearch) and I ended up by using the RegisterSynchronization method:
private void Sync(IPostDatabaseOperationEventArgs e)
{
e.Session.Transaction.RegisterSynchronization(new AfterTransactionCompletes(success =>
{
if (!success)
return;
// Do your stuff
}));
}
来源:https://stackoverflow.com/questions/50235881/onpost-events-run-before-a-commit