You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
EnlistInAmbientTransaction should not change isolation level to SERIALIZABLE if there is no ambient transaction #12
When EnlistInAmbientTransaction is called in wire-up, the default isolation level of the SQL Persistence for SQL Server is changed from the database default of READ COMMITTED to SERIALIZABLE. This can and probably should be fixed directly in NEventStore (NEventStore/NEventStore#414), but if it isn't, a workaround should be added in NEventStore.Persistence.SQL because the SQL persistence doesn't work as nicely with the SERIALIZABLE isolation level (we experienced database-level deadlocks with multiple readers/writers), and it's also much less efficient.
Reason for the SERIALIZABLE isolation level: If the TransactionScopeOption.Required is used (via code in PersistenceWireup) without specifying an isolation level, the TransactionScope default isolation level of SERIALIZABLE is used if there is no ambient transaction.
Workaround for 5.2.0: Ensure there is an active TransactionScope with ReadCommitted isolation level whenever an NEventStore API is called and EnlistInAmbientTransaction is turned on.
@HAXEN Sorry, I missed your question. First, check if you really need EnlistInAmbientTransaction, many CQRS applications will not need this option. If you do, wrap all your calls to IStoreEvents in blocks such as this one:
using (var tx = new TransactionScope (TransactionScopeOption.Required, IsolationLevel.ReadCommitted))
{
var stream = _eventStore.OpenStream(bucketId, streamId, fromRevision, int.MaxValue);
tx.Complete();
return stream;
}
Let's say I have an AggregateRoot representing a country and the key being
'sv' for sweden and 'fr' for france etc...
In order to not having duplicates into the eventstore I figure either
having the streamId = 'sv' and query that before creating a new, or having
a table languages with a primary key on countrycode.
Or
Should I make the system being able to create duplicates and in that case
having the read side "delete" the duplicate with a command? In this case
how is this usually handled regarding feedback to the user?
Being sort of new to CQRS this is not clear to me.
That said, the OpenStream API in NEventStore allows you to specify "0" as the "minimum revision" when opening a stream. This will create the stream if it doesn't exist, or read it if it does. You can then check whether the StreamRevision is 0. If it is, the stream has just been newly created. If not, it already existed. This should make it quite easy to prevent duplicates based on the stream ID.
If there's no ambiente transaction an 'EnlistInAmbientTransaction' has been called a new TransactionScope with the default ReadCommitted transaction isolation level will be generated
Activity
fschmied commentedon Mar 23, 2016
Workaround for 5.2.0: Ensure there is an active
TransactionScopewithReadCommittedisolation level whenever an NEventStore API is called andEnlistInAmbientTransactionis turned on.HAXEN commentedon May 11, 2016
@fschmied Could you provide a simple code example of how this should be done? For me as a novice to understand.
fschmied commentedon May 30, 2016
@HAXEN Sorry, I missed your question. First, check if you really need
EnlistInAmbientTransaction, many CQRS applications will not need this option. If you do, wrap all your calls toIStoreEventsin blocks such as this one:fschmied commentedon May 30, 2016
(PS:
IPersistStreamsmight also be affected, you'll need to check this yourself.)HAXEN commentedon May 30, 2016
My usecase being:
Let's say I have an AggregateRoot representing a country and the key being
'sv' for sweden and 'fr' for france etc...
In order to not having duplicates into the eventstore I figure either
having the streamId = 'sv' and query that before creating a new, or having
a table languages with a primary key on countrycode.
Or
Should I make the system being able to create duplicates and in that case
having the read side "delete" the duplicate with a command? In this case
how is this usually handled regarding feedback to the user?
Being sort of new to CQRS this is not clear to me.
On Mon, May 30, 2016 at 4:47 PM, Fabian Schmied notifications@github.com
wrote:
fschmied commentedon Jun 2, 2016
@HAXEN I guess this bug report is not the right way to discuss your specific question, better ask at https://groups.google.com/d/forum/dddcqrs for CQRS-speciifc questions or at https://groups.google.com/forum/#!forum/neventstore for NEventStore-related ones.
That said, the
OpenStreamAPI in NEventStore allows you to specify "0" as the "minimum revision" when opening a stream. This will create the stream if it doesn't exist, or read it if it does. You can then check whether theStreamRevisionis 0. If it is, the stream has just been newly created. If not, it already existed. This should make it quite easy to prevent duplicates based on the stream ID.AGiorgetti commentedon Apr 8, 2017
If there's no ambiente transaction an 'EnlistInAmbientTransaction' has been called a new TransactionScope with the default ReadCommitted transaction isolation level will be generated
Fix: #12