我正在尝试在 .Net Core 3.1 中创建示例 Web Api 项目,这有助于销售在线剧院门票。所以我添加了控制器方法,它返回当前客户端的最后一个票号:
namespace MyTestWebAPI1.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class TicketController : Controller
{
private ILogger<TicketController> _logger;
private DataContext _context;
public TicketController(ILogger<TicketController> logger, DataContext context)
{
_logger = logger;
_context = context;
}
[HttpGet]
public async Task<string> GetTicketNumber()
{
var ticketNumber = string.Empty;
using (var cmd = _context.Database.GetDbConnection().CreateCommand())
{
bool wasOpen = cmd.Connection.State == ConnectionState.Open;
if (!wasOpen) cmd.Connection.Open();
try
{
//Calling database scalar function:
cmd.CommandText = $"select Get_Next_Ticket_Number() from dual";
var scalarResult = cmd.ExecuteScalar();
ticketNumber == DBNull.Value ? string.Empty : (string)scalarResult;
}
finally
{
if (!wasOpen) cmd.Connection.Close();
}
}
//Here has other code segment which linked to save client data to database,
//for this i simpley replacing it with Task.Delay() for sample ))
await Task.Delay(20000);
return ticketNumber;
}
}
}
我怎样才能做到这个方法线程安全,那些。它没有向多个客户端返回一张票数据
答案 0 :(得分:1)
你的代码几乎就是“买一只狗然后自己吠叫”
所有这些“获取连接,运行一个 sql 找出先前插入的记录,互斥锁并锁定它以便一次只能运行一个 sql 等等等等”只是破解;如果你要进入那个兔子洞,你最好不要使用 EF。
这一切都已经为您处理好了,线程管理和并发请求也是如此,如果您按照预期使用的方式进行处理;你越是颠覆它,你就越会在 hack 之后堆积如山,让生活变得更加艰苦
答案 1 :(得分:-1)
设置索引 od 数据库列并使它们唯一。如果两个客户端同时调用GetTicketNumber,你会得到异常。