Проблема параллелизма БД с лайками постовC#

Место общения программистов C#
Ответить
Anonymous
 Проблема параллелизма БД с лайками постов

Сообщение Anonymous »

У меня есть метод Like, этот метод должен добавлять записи лайков пользователей к сообщению, а также добавлять счетчик лайков, это обычная проблема для параллелизма. что меня на самом деле беспокоит, так это maxRetryAttempts = 50, я точно не знаю, следует ли мне повторять это бесконечно или давать максимальное количество повторных попыток.
Проблема в том, что если я решу этот способ :

Код: Выделить всё

 public async Task Like(LikeDto dto)
{
async Task likeAndSave(Rating rating, bool isLiked)
{
bool like() => rating.Like(_auth.User, rating.OfferId, isLiked);
var liked = false;

try
{
liked = like();
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
_context.Entry(rating).Reload();
liked = like();
await _context.SaveChangesAsync();
//Concurrency conflic my occur again here.
}

return liked;
}

var rating = await _context.Set()
.Include(e => e.Likes.Where(e => e.User.Id == _auth.UserId))
.FirstOrDefaultAsync(e => e.OfferId == dto.Id);
var liked = await likeAndSave(rating, dto.Liked);

return rating.Analytics;
}
Затем я переработал LikeAndSave, чтобы использовать повторную попытку.

Код: Выделить всё

 public async Task Like(LikeDto dto)
{
async Task likeAndSave(bool isLiked)
{
var liked = false;

var res = await Policies.DbUpdateConcurrencyRetryPolicy.ExecuteAsync(async () =>
{
var rating = await _context.Set()
.Include(e => e.Likes.Where(e => e.User.Id == _auth.UserId))
.FirstOrDefaultAsync(e => e.OfferId == dto.Id);

liked = rating.Like(_auth.User, rating.OfferId, isLiked);

await _context.SaveChangesAsync();

return (rating, liked);
});

return res;
}

var (rating, liked) = await likeAndSave(dto.Liked);

return rating.Analytics;
}
Класс политики:

Код: Выделить всё

public static class Policies
{
public static readonly AsyncRetryPolicy DbUpdateConcurrencyRetryPolicy = Policy
.Handle()
.WaitAndRetryAsync(50, retryAttempt =>
TimeSpan.FromMilliseconds(TimeSpan.FromSeconds(2).TotalMilliseconds * Math.Pow(2, retryAttempt - 1)));
}
Объекты:

Код: Выделить всё

public class Post
{
public Analytics Social { get; set; }
}

public class Rating
{
public List Ratings { get; set; } = new();
public List Reports { get; set; } = new();
public List Likes { get; set; } = new();
public List Dislikes { get; set; } = new();
public List Comments { get; set; } = new();
public List Shares { get; set; } = new();
public Analytics Analytics { get; set; }
public int PostId { get; set; }
}

public class Analytics
{
public int TotalViews { get; set; }
public int TotalRatings { get; set; }
public int TotalReports { get; set; }
public int TotalLikes { get; set; }
public int TotalDislikes { get; set; }
public int TotalShares { get; set; }
public int TotalComments { get; set; }
public double AverageRating { get; set; }
}
Метод работает, отлично, просто интересно узнать о политике повторных попыток, есть ли что-нибудь более безопасное, чем это.

Подробнее здесь: https://stackoverflow.com/questions/791 ... post-likes
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»