ASP.NET MVC web 应用程序访问和修改数据库的最佳实践
ASP.NET MVC web application access and modify database recurrently best practice
我的应用程序用户有一个余额属性,只要他们激活了服务就需要更新。到目前为止,更新功能使用每小时 运行 的 .net webjob(网络作业最多可以 运行 每小时共享或基本订阅)。
是否有更好的解决方案来实现余额更新功能?我还考虑过在 Application_Start()
上按以下方式进行操作:
public class MvcApplication : System.Web.HttpApplication
{
private ApplicationDbContext db = new ApplicationDbContext();
private PaymentsController paymentsController = new PaymentsController();
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Timer tmr = new Timer();
tmr.Interval = 60000; //1 minute
tmr.Elapsed += updateUsersBalance;
tmr.Start();
}
private void updateUsersBalance(Object source, System.Timers.ElapsedEventArgs e)
{
var users = db.Users.ToList();
foreach (var user in users)
{
user.balance -= 1;
db.Entry(user).State = EntityState.Modified;
}
db.SaveChanges(); //save updated balances
}
这是每分钟更新一次余额的可靠机制吗?在 Global.cs
文件中引用数据库和控制器是否可以?
(撇开计时器的精度不谈)
在我的例子中,这种情况比 webjob 更可取,因为我每小时最多可以 运行 它们的限制。
不,这本身并不是一个可靠的方法。 IIS 有可能关闭应用程序池,因此您的循环不会是 运行。您可以通过设置 ASP.NET Auto-Start (in Azure there is an "Always On" switch in the Configuration page to enable it) but really a job runner is probably the better option (in addition to ASP.NET Auto-Start). Maybe checkout Hangfire (which is what we are currently using) or Quartz.net
来解决这个问题
@nest 我不明白你的架构到底是什么,但我想我明白你需要什么。
每分钟更新您的余额是虚拟的,想一想:"Why you need to update your balance if no one read it?"
考虑到这一点,您可以断言只要有人访问您的余额就会更新。这样可以节省处理资源。所以你不需要为每分钟 运行 这个过程而烦恼,你需要 运行 每次都有变化并且为了冗余你可以在访问之前重新计算。
那是说你可以使用 Job Scheduler 来计算余额,我建议 Hangfire,每次有人更改值时强制 Job 运行 并安排到 运行间隔或强制 运行 如果某人访问不满足该间隔。
当然,这种方式你需要更改为 Web 角色,主要是因为 Hangfire 有一个 Web 界面可以让你管理你的工作。
我的应用程序用户有一个余额属性,只要他们激活了服务就需要更新。到目前为止,更新功能使用每小时 运行 的 .net webjob(网络作业最多可以 运行 每小时共享或基本订阅)。
是否有更好的解决方案来实现余额更新功能?我还考虑过在 Application_Start()
上按以下方式进行操作:
public class MvcApplication : System.Web.HttpApplication
{
private ApplicationDbContext db = new ApplicationDbContext();
private PaymentsController paymentsController = new PaymentsController();
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Timer tmr = new Timer();
tmr.Interval = 60000; //1 minute
tmr.Elapsed += updateUsersBalance;
tmr.Start();
}
private void updateUsersBalance(Object source, System.Timers.ElapsedEventArgs e)
{
var users = db.Users.ToList();
foreach (var user in users)
{
user.balance -= 1;
db.Entry(user).State = EntityState.Modified;
}
db.SaveChanges(); //save updated balances
}
这是每分钟更新一次余额的可靠机制吗?在 Global.cs
文件中引用数据库和控制器是否可以?
(撇开计时器的精度不谈)
在我的例子中,这种情况比 webjob 更可取,因为我每小时最多可以 运行 它们的限制。
不,这本身并不是一个可靠的方法。 IIS 有可能关闭应用程序池,因此您的循环不会是 运行。您可以通过设置 ASP.NET Auto-Start (in Azure there is an "Always On" switch in the Configuration page to enable it) but really a job runner is probably the better option (in addition to ASP.NET Auto-Start). Maybe checkout Hangfire (which is what we are currently using) or Quartz.net
来解决这个问题@nest 我不明白你的架构到底是什么,但我想我明白你需要什么。
每分钟更新您的余额是虚拟的,想一想:"Why you need to update your balance if no one read it?"
考虑到这一点,您可以断言只要有人访问您的余额就会更新。这样可以节省处理资源。所以你不需要为每分钟 运行 这个过程而烦恼,你需要 运行 每次都有变化并且为了冗余你可以在访问之前重新计算。
那是说你可以使用 Job Scheduler 来计算余额,我建议 Hangfire,每次有人更改值时强制 Job 运行 并安排到 运行间隔或强制 运行 如果某人访问不满足该间隔。
当然,这种方式你需要更改为 Web 角色,主要是因为 Hangfire 有一个 Web 界面可以让你管理你的工作。