/// <summary> /// Execute a process transaction /// Warning: you need to execute this method inside a Transaction (TransactionScope) /// this is how you control if the changes will be saved to the db. /// @param persMode - persistence mode /// /// assume we have all process tasks in a single record /// so when performing modification, we need to limit our scope to that record (this process instance) /// and all messages leaving the process will be handled async /// so we divide our messages between in-process and inter-process /// inter-process are always async /// in-process are sync when they're task control messages /// async when they are from send/receive message tasks (hmmm, this doesn't really matter when in proc) /// /// what about transactions? /// - we assume we're already inside a system transaction /// - we can get an external db connection. If we don't get it, we need to open it. /// - process session /// - other components should have an option to be notified about commit - use system.transactions api... /// </summary> public void RunProcessTransaction(TaskPersistenceMode persMode, Action <ProcessSession> act) { if (ProcessSession.Current != null) { act(ProcessSession.Current); return; } Queue <ProcessMessage> outgoing = null; InSystemTransaction(() => { InDbTransaction(SessionFactory, dbs => { var pess = TaskPersister.OpenSession(dbs); pess.PersistenceMode = persMode; var ps = new ProcessSession(pess, MessageBus, ServiceResolver); try { ProcessSession.Current = ps; ps.MessageBus = MessageBus; ps.TaskPersister = pess; act(ps); PumpMessages(ps); outgoing = ps.AsyncQueue; } finally { ProcessSession.Current = null; ps.Dispose(); } pess.SaveChanges(); pess.Dispose(); }); }); if (outgoing != null) { foreach (var pm in outgoing) { SendLocalAsyncMessage(pm); } } }
protected void RunProcessTransaction(TaskPersistenceMode persMode, Action <ProcessSession> act) { if (ProcessSession.Current != null) { act(ProcessSession.Current); return; } IEnumerable <ProcessMessage> outgoing = null; InSystemTransaction(() => { InDbTransaction(dbs => { using (var pess = TaskPersister.OpenSession(dbs)) { pess.PersistenceMode = persMode; Services.TaskPersisterSession.Current = pess; using (var ps = ProcessSession.CreateNew(this, pess)) { ProcessSession.Current = ps; act(ps); ps.PumpMessages(); outgoing = ps.GetOutgoingAsyncMessages(); } pess.SaveChanges(); Services.TaskPersisterSession.Current = null; } }); }); if (outgoing != null) { foreach (var pm in outgoing) { SendLocalAsyncMessage(pm); } } }