Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [Transaction] Lifecycle events for nested transactions
[Transaction] Lifecycle events for nested transactions [message #1828193] Wed, 03 June 2020 14:42 Go to next message
Felix Dorner is currently offline Felix DornerFriend
Messages: 391
Registered: December 2015
Senior Member
Hi,

I am confused about this documentation vs behaviour discrepancy:

The doc for TransactionalEditingDomainListener.transactionStarted() states:

"Signals that a transaction has been activated. This event is not sent for nested transactions, nor for a transaction'sresumption from the yielded state. "

Now, if I run a write command which triggers a precommit command, the order of received events is:

Start Start Stop Stop. So, no matter how I try to think through, this looks like a bug, either in code or documentation:

A precommit transaction is either nested or not:

a) If a precommit transaction is a nested transaction, then there should only be one start/stop notification (or the documentation is wrong)

b) If a precommit transaction is not a nested transaction, then the order should be
start stop start stop

Am I missing something?

For my specific usecase, I only want to know if a transaction is active or not, so I can still do that by maintaining a stack, where start events push, and stop events pop, so no dealbreaker, but still it feels weird.
Re: [Transaction] Lifecycle events for nested transactions [message #1828196 is a reply to message #1828193] Wed, 03 June 2020 15:24 Go to previous messageGo to next message
Christian Damus is currently offline Christian DamusFriend
Messages: 1246
Registered: July 2009
Location: Canada
Senior Member

Hi, Felix,

That was the intention initially, that the started/closed events were only sent for root transactions. And the TransactionImpl::start() method looks like it will only send the started event for a root transaction.

Is it possible that you have a transaction implementation that overrides this? Or that you actually have two different editing domains, each with a root transaction?

Or perhaps the nested transactions involved in the pre-commit processing are a special case that for whatever reason does notify. Do you see the same pattern of notifications for a nested "user transaction"? (i.e., one created explicitly by the application or perhaps indirectly via nested AbstractEMFOperations)

HTH,

Christian
Re: [Transaction] Lifecycle events for nested transactions [message #1828218 is a reply to message #1828196] Thu, 04 June 2020 09:17 Go to previous messageGo to next message
Felix Dorner is currently offline Felix DornerFriend
Messages: 391
Registered: December 2015
Senior Member
No, no special cases here, single simple test.

It really seems that the documentation does not apply to the precommit transactions. TransactionImpl.deactivate() sets activeTransaction to null, then processes precommits, and since active transaction is null, a new Transaction is started, triggering the second start notification. Only after that. Here's a stack that stops at the second received start event:

LifeCycleTests$2.transactionStarted(TransactionalEditingDomainEvent) line: 48
TransactionalEditingDomainImpl$LifecycleImpl.fireLifecycleEvent(int, Transaction) line: 1377
TransactionalEditingDomainImpl$LifecycleImpl.transactionStarted(InternalTransaction) line: 1418
TransactionImpl.start() line: 268
TransactionalEditingDomainImpl.startTransaction(boolean, Map<?,?>) line: 424
TransactionalEditingDomainImpl.runExclusive(Runnable) line: 321
TransactionalEditingDomainImpl.postcommit(InternalTransaction) line: 771
TransactionalEditingDomainImpl.deactivate(InternalTransaction) line: 543
EMFCommandTransaction(TransactionImpl).close() line: 712
EMFCommandTransaction(TransactionImpl).commit() line: 474
Re: [Transaction] Lifecycle events for nested transactions [message #1828224 is a reply to message #1828218] Thu, 04 June 2020 11:25 Go to previous messageGo to next message
Felix Dorner is currently offline Felix DornerFriend
Messages: 391
Registered: December 2015
Senior Member
Sorry, my description is plain wrong. A precommit listener isn't even needed. It's the postcommit execution that causes the nested start/stop cycle. I just realized that from looking at the stack in my previous comment. The good thing about this, is the example gets even simpler:

class LifeCycleTests {
  @Test
  void testPostCommitLifeCycle() {
    TransactionalEditingDomain domain = new TransactionalEditingDomainImpl(new AdapterFactoryImpl());
    Lifecycle lc = TransactionUtil.getAdapter(domain, Lifecycle.class);
    lc.addTransactionalEditingDomainListener(new TransactionalEditingDomainListenerImpl() {
      @Override
      public void transactionClosed(TransactionalEditingDomainEvent event) {
        System.out.println("closed " + event + " readOnly: " + event.getTransaction().isReadOnly());
      }
      @Override
      public void transactionStarted(TransactionalEditingDomainEvent event) {
        System.out.println("start " + event + " readOnly: " + event.getTransaction().isReadOnly());
      }
    });
    domain.getCommandStack().execute(new RecordingCommand(domain) {
      @Override
      protected void doExecute() {
        domain.getResourceSet().getResources().add(new ResourceImpl());
      }
    });
  }
}


This prints out
tart org.eclipse.emf.transaction.TransactionalEditingDomainEvent[source=org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl@6042b613] readOnly: false
start org.eclipse.emf.transaction.TransactionalEditingDomainEvent[source=org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl@6042b613] readOnly: true
closed org.eclipse.emf.transaction.TransactionalEditingDomainEvent[source=org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl@6042b613] readOnly: true
closed org.eclipse.emf.transaction.TransactionalEditingDomainEvent[source=org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl@6042b613] readOnly: false


So probably you can say: A postcommit transaction is a root transaction, and because of that, I get the second start, just the order in which the start/close are dispached is confusing.

[Updated on: Thu, 04 June 2020 11:25]

Report message to a moderator

Re: [Transaction] Lifecycle events for nested transactions [message #1828225 is a reply to message #1828224] Thu, 04 June 2020 11:30 Go to previous messageGo to next message
Christian Damus is currently offline Christian DamusFriend
Messages: 1246
Registered: July 2009
Location: Canada
Senior Member

Hi, Felix,

Thanks for looking into this in such detail. This makes sense. My memory is now very fuzzy after the passage of years, but I do recall that it necessary for the read-only transaction that notifies post-commit listeners to be a root (it is *post* commit, after all) but also that the application in which this API had its origins needed notification of closure of the original transaction only after all post-commit processing had completed.

So, yes, this is an exceptional case vis-a-vis the listener API documentation that you originally cited, which IMO should be amended to call it out. I should have done that a decade ago :-/

Thanks!
Christian
Re: [Transaction] Lifecycle events for nested transactions [message #1828227 is a reply to message #1828225] Thu, 04 June 2020 12:14 Go to previous message
Felix Dorner is currently offline Felix DornerFriend
Messages: 391
Registered: December 2015
Senior Member
Doesn't matter, as I said, I can live with this behaviour, using a stack.
It is however quite awesome that you're still monitoring the forum like an addict. Thank's a lot Christian.

Felix
Previous Topic:[CDO] Offline Clone keeps connecting and disconnecting to master
Next Topic:Is there a way to delete the data EList (Xcore) from my tableviewer faster?
Goto Forum:
  


Current Time: Thu Apr 15 12:10:24 GMT 2021

Powered by FUDForum. Page generated in 0.02075 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top