In my MVC application, I have a page that loads a record from my POLICIES table and then uses it in my View. My View then has the data from this record displayed on the page, however in order to edit the record data the user needs to click the "Edit Policy" button, which launches a jQuery UI dialog with the same record in EDIT mode. I realize I could just allow them to edit it from the main View, however that is not what my client wants.
The trouble I'm having is, when I'm in my jQuery UI Dialog, I get the error below when I try to save the record.
FirebirdSql.Data.FirebirdClient.FbException: lock conflict on no wait transaction
The Controller method for my dialog executes the following code. The PolicyModel is simply a class which serves as the ViewModel for the dialog, and the Policy property is an object representing the Policy table.
public ActionResult Policy(int policyNo) {
PolicyModel policyModel = new PolicyModel();
policyModel.Policy = dbContext.POLICIES.FirstOrDefault(db => db.POLICY_NO == policyNo);
return View(policyModel);
}
In the "Policy" View, I do a standard form using:
@using (Html.BeingForm("SavePolicy", "MyController", FormMethod.Post)) {
//hidden element for policyNo created with @Html.HiddenFor
//form elements here created using the @Html.TextBoxFor..etc.
}
The dialog button to save simply creates new FormData with var formData = new FormData($('#myformid').get(0)); I then pass that to my save controller method.
The Save method is set up like the following
public ActionResult SavePolicy(PolicyModel policyModel) {
var policy = dbContext.POLICIES.FirstOrDefault(db => db.POLICY_NO == policyModel.POLICY_NO);
if (TryUpdateModel(policy,"Policy", updateFields.ToArray())) {
dbContext.Entry(policy).State = EntityState.Modified;
dbContext.SaveChanges();
}
return Json( new { result = 1, JsonRequestBehavior.AllowGet } );
}
If I change the POLICY_NO manually though to ANY other policy number than the one currently active in the dialog like this...
var policy = dbContext.POLICIES.FirstOrDefault(db => db.POLICY_NO == 12345);
The save will update correctly.
It's like the dialog View is holding onto the resource or something. any ideas?
UPDATE
For reference, the dbContext is scoped to the Controller class in which my SavePolicy method lives as seen below...
public class MainController : Controller {
private DBModel dbContext = new DBModel();
// other methods
public ActionResult SavePolicy(PolicyModel policyModel) {
// method code as see above
}
}
ASP.NET MVC Controllers usually have this:
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
So, if you are declaring your context outside of your action, you should verify if this method is implemented.
Turns out that, at the first execution (a select), your context keeps track of the record at Firebird and it is never disposed. The second execution will try to select the same entry again, which is still tracked by another context that was not disposed properly.
Using the scoped context inside each action is another way to solve, but it is a bit more cumbersome in my standpoint.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With