diff --git a/LiteDB.Tests/Issues/Issue2471_Test.cs b/LiteDB.Tests/Issues/Issue2471_Test.cs new file mode 100644 index 000000000..82ee87cd0 --- /dev/null +++ b/LiteDB.Tests/Issues/Issue2471_Test.cs @@ -0,0 +1,36 @@ +using FluentAssertions; + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +using Xunit; + +namespace LiteDB.Tests.Issues; + +public class Issue2471_Test +{ + [Fact] + public void TestFragmentDB_FindByIDException() + { + using var db = new LiteDatabase(":memory:"); + var collection = db.GetCollection("fragtest"); + + var fragment = new object { }; + var id = collection.Insert(fragment); + + id.Should().BeGreaterThan(0); + + var frag2 = collection.FindById(id); + frag2.Should().NotBeNull(); + + Action act = () => db.Checkpoint(); + + //act.Should().Throw(); + act.Should().NotThrow(); + } +} \ No newline at end of file diff --git a/LiteDB/Engine/Query/QueryExecutor.cs b/LiteDB/Engine/Query/QueryExecutor.cs index 10d8e034b..60034e132 100644 --- a/LiteDB/Engine/Query/QueryExecutor.cs +++ b/LiteDB/Engine/Query/QueryExecutor.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using static LiteDB.Constants; @@ -130,28 +130,9 @@ IEnumerable RunQuery() using (var enumerator = pipe.Pipe(nodes, queryPlan).GetEnumerator()) { - var read = false; - try { - read = enumerator.MoveNext(); - } - catch (Exception ex) - { - _state.Handle(ex); - throw ex; - } - - while (read) - { - _cursor.Fetched++; - _cursor.Elapsed.Stop(); - - yield return enumerator.Current; - - if (transaction.State != TransactionState.Active) throw new LiteException(0, $"There is no more active transaction for this cursor: {_cursor.Query.ToSQL(_cursor.Collection)}"); - - _cursor.Elapsed.Start(); + var read = false; try { @@ -162,6 +143,36 @@ IEnumerable RunQuery() _state.Handle(ex); throw ex; } + + while (read) + { + _cursor.Fetched++; + _cursor.Elapsed.Stop(); + + yield return enumerator.Current; + + if (transaction.State != TransactionState.Active) throw new LiteException(0, $"There is no more active transaction for this cursor: {_cursor.Query.ToSQL(_cursor.Collection)}"); + + _cursor.Elapsed.Start(); + + try + { + read = enumerator.MoveNext(); + } + catch (Exception ex) + { + _state.Handle(ex); + throw ex; + } + } + } + finally + { + if (isNew) + { + _monitor.ReleaseTransaction(transaction); + isNew = false; + } } }