<commit_before>﻿// Copyright (c) 2007-2018 ppy Pty Ltd <<EMAIL>>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using System;
using Microsoft.EntityFrameworkCore.Storage;

namespace osu.Game.Database
{
    public class DatabaseWriteUsage : IDisposable
    {
        public readonly OsuDbContext Context;
        private readonly IDbContextTransaction transaction;
        private readonly Action<DatabaseWriteUsage> usageCompleted;

        public DatabaseWriteUsage(OsuDbContext context, Action<DatabaseWriteUsage> onCompleted)
        {
            Context = context;
            transaction = Context.BeginTransaction();
            usageCompleted = onCompleted;
        }

        public bool PerformedWrite { get; private set; }

        private bool isDisposed;

        protected void Dispose(bool disposing)
        {
            if (isDisposed) return;
            isDisposed = true;

            PerformedWrite |= Context.SaveChanges(transaction) > 0;
            usageCompleted?.Invoke(this);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~DatabaseWriteUsage()
        {
            Dispose(false);
        }
    }
}
<commit_msg>Add proper transaction rollback logic on exception<commit_after>﻿// Copyright (c) 2007-2018 ppy Pty Ltd <<EMAIL>>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using System;
using Microsoft.EntityFrameworkCore.Storage;

namespace osu.Game.Database
{
    public class DatabaseWriteUsage : IDisposable
    {
        public readonly OsuDbContext Context;
        private readonly IDbContextTransaction transaction;
        private readonly Action<DatabaseWriteUsage> usageCompleted;

        public DatabaseWriteUsage(OsuDbContext context, Action<DatabaseWriteUsage> onCompleted)
        {
            Context = context;
            transaction = Context.BeginTransaction();
            usageCompleted = onCompleted;
        }

        public bool PerformedWrite { get; private set; }

        private bool isDisposed;

        protected void Dispose(bool disposing)
        {
            if (isDisposed) return;
            isDisposed = true;

            try
            {
                PerformedWrite |= Context.SaveChanges(transaction) > 0;
            }
            catch (Exception e)
            {
                transaction?.Rollback();
                throw;
            }
            finally
            {
                usageCompleted?.Invoke(this);
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~DatabaseWriteUsage()
        {
            Dispose(false);
        }
    }
}

{'fraction_non_alphanumeric': 0.07809726659566915, 'fraction_numerical': 0.006389776357827476, 'mean_word_length': 1.9141675284384696, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2635525', 'n_tokens_mistral': 722, 'n_tokens_neox': 688, 'n_words': 165}