mirror of
https://github.com/ppy/osu.git
synced 2025-01-07 18:33:04 +08:00
Merge pull request #19027 from peppy/realm-nested-writes
Add nested transaction handling to realm helper methods
This commit is contained in:
commit
c8b05a5ef2
@ -59,6 +59,64 @@ namespace osu.Game.Tests.Database
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFailedWritePerformsRollback()
|
||||||
|
{
|
||||||
|
RunTestWithRealm((realm, _) =>
|
||||||
|
{
|
||||||
|
Assert.Throws<InvalidOperationException>(() =>
|
||||||
|
{
|
||||||
|
realm.Write(r =>
|
||||||
|
{
|
||||||
|
r.Add(new BeatmapInfo(CreateRuleset(), new BeatmapDifficulty(), new BeatmapMetadata()));
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.That(realm.Run(r => r.All<BeatmapInfo>()), Is.Empty);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFailedNestedWritePerformsRollback()
|
||||||
|
{
|
||||||
|
RunTestWithRealm((realm, _) =>
|
||||||
|
{
|
||||||
|
Assert.Throws<InvalidOperationException>(() =>
|
||||||
|
{
|
||||||
|
realm.Write(r =>
|
||||||
|
{
|
||||||
|
realm.Write(_ =>
|
||||||
|
{
|
||||||
|
r.Add(new BeatmapInfo(CreateRuleset(), new BeatmapDifficulty(), new BeatmapMetadata()));
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.That(realm.Run(r => r.All<BeatmapInfo>()), Is.Empty);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNestedWriteCalls()
|
||||||
|
{
|
||||||
|
RunTestWithRealm((realm, _) =>
|
||||||
|
{
|
||||||
|
var beatmap = new BeatmapInfo(CreateRuleset(), new BeatmapDifficulty(), new BeatmapMetadata());
|
||||||
|
|
||||||
|
var liveBeatmap = beatmap.ToLive(realm);
|
||||||
|
|
||||||
|
realm.Run(r =>
|
||||||
|
r.Write(_ =>
|
||||||
|
r.Write(_ =>
|
||||||
|
r.Add(beatmap)))
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.IsFalse(liveBeatmap.PerformRead(l => l.Hidden));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAccessAfterAttach()
|
public void TestAccessAfterAttach()
|
||||||
{
|
{
|
||||||
|
@ -8,20 +8,61 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
public static class RealmExtensions
|
public static class RealmExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Perform a write operation against the provided realm instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This will automatically start a transaction if not already in one.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="realm">The realm to operate on.</param>
|
||||||
|
/// <param name="function">The write operation to run.</param>
|
||||||
public static void Write(this Realm realm, Action<Realm> function)
|
public static void Write(this Realm realm, Action<Realm> function)
|
||||||
{
|
{
|
||||||
using var transaction = realm.BeginWrite();
|
Transaction? transaction = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!realm.IsInTransaction)
|
||||||
|
transaction = realm.BeginWrite();
|
||||||
|
|
||||||
function(realm);
|
function(realm);
|
||||||
transaction.Commit();
|
|
||||||
|
transaction?.Commit();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
transaction?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Perform a write operation against the provided realm instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This will automatically start a transaction if not already in one.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="realm">The realm to operate on.</param>
|
||||||
|
/// <param name="function">The write operation to run.</param>
|
||||||
public static T Write<T>(this Realm realm, Func<Realm, T> function)
|
public static T Write<T>(this Realm realm, Func<Realm, T> function)
|
||||||
{
|
{
|
||||||
using var transaction = realm.BeginWrite();
|
Transaction? transaction = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!realm.IsInTransaction)
|
||||||
|
transaction = realm.BeginWrite();
|
||||||
|
|
||||||
var result = function(realm);
|
var result = function(realm);
|
||||||
transaction.Commit();
|
|
||||||
|
transaction?.Commit();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
transaction?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the provided change set has changes to the top level collection.
|
/// Whether the provided change set has changes to the top level collection.
|
||||||
|
Loading…
Reference in New Issue
Block a user