fixes #311 - Database connection became corrupted

This commit is contained in:
Luke Pulverenti 2013-05-25 14:00:34 -04:00
parent aa2cb17cdb
commit 084557ca46

View File

@ -6,6 +6,7 @@ using MediaBrowser.Model.Serialization;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Data.SQLite;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -22,6 +23,8 @@ namespace MediaBrowser.Server.Implementations.Sqlite
/// </summary> /// </summary>
public const string RepositoryName = "SQLite"; public const string RepositoryName = "SQLite";
private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1);
/// <summary> /// <summary>
/// Gets the name of the repository /// Gets the name of the repository
/// </summary> /// </summary>
@ -115,32 +118,51 @@ namespace MediaBrowser.Server.Implementations.Sqlite
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
SQLiteTransaction transaction = null;
try
{
transaction = Connection.BeginTransaction();
using (var cmd = Connection.CreateCommand()) using (var cmd = Connection.CreateCommand())
{ {
cmd.CommandText = "replace into users (guid, data) values (@1, @2)"; cmd.CommandText = "replace into users (guid, data) values (@1, @2)";
cmd.AddParam("@1", user.Id); cmd.AddParam("@1", user.Id);
cmd.AddParam("@2", serialized); cmd.AddParam("@2", serialized);
using (var tran = Connection.BeginTransaction()) cmd.Transaction = transaction;
{
try
{
cmd.Transaction = tran;
await cmd.ExecuteNonQueryAsync(cancellationToken); await cmd.ExecuteNonQueryAsync(cancellationToken);
}
tran.Commit(); transaction.Commit();
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
tran.Rollback(); if (transaction != null)
{
transaction.Rollback();
}
} }
catch (Exception e) catch (Exception e)
{ {
Logger.ErrorException("Failed to commit transaction.", e); Logger.ErrorException("Failed to save user:", e);
tran.Rollback();
if (transaction != null)
{
transaction.Rollback();
} }
} }
finally
{
if (transaction != null)
{
transaction.Dispose();
}
_writeLock.Release();
} }
} }
@ -175,7 +197,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">user</exception> /// <exception cref="System.ArgumentNullException">user</exception>
public Task DeleteUser(User user, CancellationToken cancellationToken) public async Task DeleteUser(User user, CancellationToken cancellationToken)
{ {
if (user == null) if (user == null)
{ {
@ -189,13 +211,52 @@ namespace MediaBrowser.Server.Implementations.Sqlite
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
SQLiteTransaction transaction = null;
try
{
transaction = Connection.BeginTransaction();
using (var cmd = Connection.CreateCommand()) using (var cmd = Connection.CreateCommand())
{ {
cmd.CommandText = "delete from users where guid=@guid"; cmd.CommandText = "delete from users where guid=@guid";
var guidParam = cmd.Parameters.Add("@guid", DbType.Guid); var guidParam = cmd.Parameters.Add("@guid", DbType.Guid);
guidParam.Value = user.Id; guidParam.Value = user.Id;
return ExecuteCommand(cmd); cmd.Transaction = transaction;
await ExecuteCommand(cmd).ConfigureAwait(false);
}
transaction.Commit();
}
catch (OperationCanceledException)
{
if (transaction != null)
{
transaction.Rollback();
}
}
catch (Exception e)
{
Logger.ErrorException("Failed to delete user:", e);
if (transaction != null)
{
transaction.Rollback();
}
}
finally
{
if (transaction != null)
{
transaction.Dispose();
}
_writeLock.Release();
} }
} }
} }