{"action":"created","issue":{"url":"https://api.github.com/repos/MassTransit/MassTransit/issues/745","repository_url":"https://api.github.com/repos/MassTransit/MassTransit","labels_url":"https://api.github.com/repos/MassTransit/MassTransit/issues/745/labels{/name}","comments_url":"https://api.github.com/repos/MassTransit/MassTransit/issues/745/comments","events_url":"https://api.github.com/repos/MassTransit/MassTransit/issues/745/events","html_url":"https://github.com/MassTransit/MassTransit/pull/745","id":197791084,"number":745,"title":"Add EF Optimistic Concurrency Alternative to using Database Locking f…","user":{"login":"maldworth","id":187903,"avatar_url":"https://avatars.githubusercontent.com/u/187903?v=3","gravatar_id":"","url":"https://api.github.com/users/maldworth","html_url":"https://github.com/maldworth","followers_url":"https://api.github.com/users/maldworth/followers","following_url":"https://api.github.com/users/maldworth/following{/other_user}","gists_url":"https://api.github.com/users/maldworth/gists{/gist_id}","starred_url":"https://api.github.com/users/maldworth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/maldworth/subscriptions","organizations_url":"https://api.github.com/users/maldworth/orgs","repos_url":"https://api.github.com/users/maldworth/repos","events_url":"https://api.github.com/users/maldworth/events{/privacy}","received_events_url":"https://api.github.com/users/maldworth/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-12-28T03:40:26Z","updated_at":"2017-01-03T02:53:55Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/MassTransit/MassTransit/pulls/745","html_url":"https://github.com/MassTransit/MassTransit/pull/745","diff_url":"https://github.com/MassTransit/MassTransit/pull/745.diff","patch_url":"https://github.com/MassTransit/MassTransit/pull/745.patch"},"body":"## Pull Req\r\n\r\nOkay so this Pull Request allows Optimistic Concurrency with EntityFramework. You can implement it [two different ways](http://www.binaryintellect.net/articles/14e67064-634c-4206-9eca-a42d3739594a.aspx) in EF. The benefit (obviously) is no row/page locks. However you will then need to retry the saga transaction if you get the DbUpdateConcurrencyException. Since the middleware .UseRetry gives us this capability, I made some concurrency unit tests to check. I put in three.\r\n\r\n* **UsingEntityFrameworkConcurrencyPessimistic_Specs.cs** - Uses database locks (as it does today, no changes)\r\n* **UsingEntityFrameworkConcurrencyOptimistic_Specs.cs** - Uses EF RowVersion (Timestamp). Leverages UseRetry() for DbUpdateConcurrencyException\r\n* **UsingEntityFrameworkConcurrencyFail_Specs.cs** - The negative test. Still sets the optimistic: true flag, but omit's the UseRetry(). This shows how important it is to use the retry middleware if you opt-in for optimistic.\r\n\r\nWhen passing the constructor param optimistic: true into `EntityFrameworkSagaRepository`, it should be noted that it's very important to ensure in your SagaMap, that you have a property mapped to RowVersion with the fluent mapping:\r\n```csharp\r\nProperty(x => x.RowVersion)\r\n    .IsRowVersion();\r\n```\r\n\r\nAs well as make sure to have a UseRetry middleware to retry the `DbUpdateConcurrencyException`.\r\n\r\nIf this PR is accepted, I might write a bit of documentation for the RTD page to illustrate how this feature can be used.\r\n\r\n## Unrelated Notes\r\n\r\nSome other things I noted when I was working with these unit tests\r\n\r\nThe change you made [here](https://github.com/MassTransit/MassTransit/commit/12eaf9aed9325c301253c3637042f372e9734a59) seems to have added the explicit `Should_handle_the_big_load()` test, but if I comment out `catch (DbUpdateException ex)` in the `class EntityFrameworkSagaRepository`, the unit test still passes. So it doesn't appear to test the original intent (https://groups.google.com/d/msg/masstransit-discuss/36GzkVl3SWQ/kBRrdcjECwAJ)\r\n\r\nAnother interesting thing to note, if I remove the two spots where you lock the data (simply by passing optimistic: true), and run that test `Should_handle_the_big_load()`, then the unit test fails with an internal `EntityException (Timeout expired.. for obtaining a connection from the connection pool...)`\r\n\r\nI think this is because the default connection pool for LocalDb (SQL Server) is 100, and the 200 is depleting all the connections from the pool. Anyways, this seems to be unrelated to the Optimistic change I made, but thought I'd let you know about it.\r\n\r\nThanks"},"comment":{"url":"https://api.github.com/repos/MassTransit/MassTransit/issues/comments/270044858","html_url":"https://github.com/MassTransit/MassTransit/pull/745#issuecomment-270044858","issue_url":"https://api.github.com/repos/MassTransit/MassTransit/issues/745","id":270044858,"user":{"login":"maldworth","id":187903,"avatar_url":"https://avatars.githubusercontent.com/u/187903?v=3","gravatar_id":"","url":"https://api.github.com/users/maldworth","html_url":"https://github.com/maldworth","followers_url":"https://api.github.com/users/maldworth/followers","following_url":"https://api.github.com/users/maldworth/following{/other_user}","gists_url":"https://api.github.com/users/maldworth/gists{/gist_id}","starred_url":"https://api.github.com/users/maldworth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/maldworth/subscriptions","organizations_url":"https://api.github.com/users/maldworth/orgs","repos_url":"https://api.github.com/users/maldworth/repos","events_url":"https://api.github.com/users/maldworth/events{/privacy}","received_events_url":"https://api.github.com/users/maldworth/received_events","type":"User","site_admin":false},"created_at":"2017-01-03T02:53:55Z","updated_at":"2017-01-03T02:53:55Z","body":"Rebased of latest develop to get the changes for broken unit tests."}}
{"actor":{"display_login":"maldworth"}}