System.Data.SqlClient.SqlException:不允许新事务,因为会话中还有其他线程在运行。 MVC

时间:2016-02-15 01:51:04

标签: c# html asp.net-mvc asp.net-mvc-4

我正在尝试单独更新每个产品,其中多个产品可以在一个订单中找到。当我按提交/更新时,我将orderid与新产品数量一起发送到控制器。这是我显示的错误:“System.Data.SqlClient.SqlException:不允许新事务,因为会话中还有其他线程运行。”

这是重定向到表单的控制器。

[HttpGet]
    [Authorize(Roles = "ADM")]
    public ActionResult UpdateDetails(Guid id)
    {
        BusinessLayer.Orders blorder = new BusinessLayer.Orders();
        return View(blorder.GetOrderDetailsByOrderId(id));
    }

这是表格。

@model IQueryable<CommonLayer.ORDERDETAIL>
@{
    ViewBag.Title = "UpdateDetails";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>UpdateDetails</h2>


<table class="table table-striped" style="font-size:medium;">
    <tr>

        <th>
            Order Details ID
        </th>
        <th>
            Price
        </th>
        <th>
            VAT Rate
        </th>
        <th>
            Quantity
        </th>
    </tr>

    @foreach (var item in Model)
    {

            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.OrderDetailsId)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ProductPrice)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ProductVATRate)
                </td>
                <td>
                    <form action="/order/updatedetails/@item.OrderDetailsId" method="post" enctype="multipart/form-data">
                        <input type="text" name="prodqty" value="@item.ProductQuantity" />
                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-10">
                                <br />
                                <input type="submit" value="Update" class="btn btn-primary" />
                            </div>
                        </div>
                    </form>
                </td>
            </tr>
        }

</table>

这是表单重定向到的控制器。

[HttpPost]
    [Authorize(Roles = "ADM")]
    public ActionResult UpdateDetails(Guid id, int prodqty)
    {
        BusinessLayer.Orders blorder = new BusinessLayer.Orders();
        CommonLayer.ORDERDETAIL orderdetail = blorder.GetOrderDetailByDetailId(id);
        blorder.UpdateOrderDetails(orderdetail, prodqty);
        return RedirectToAction("ViewOrder");
    }

这是用于实际更新股票的代码。

public void UpdateOrderDetails(CommonLayer.ORDERDETAIL orderdetail, int prodqty)
    {
            CommonLayer.ORDERDETAIL orderDetails = this.GetOrderDetail(orderdetail.OrderDetailsOrderId);
            CommonLayer.ORDERDETAIL od = new CommonLayer.ORDERDETAIL();
            DataLayer.DAProducts daprod = new DataLayer.DAProducts(this.Entities);
            CommonLayer.PRODUCT product = daprod.GetProduct(orderDetails.OrderDetailsProductId);

            od.OrderDetailsProductId = orderDetails.OrderDetailsProductId;
            od.OrderDetailsId = orderDetails.OrderDetailsId;
            od.OrderDetailsOrderId = orderDetails.OrderDetailsOrderId;
            od.ProductVATRate = orderDetails.ProductVATRate;
            od.ProductPrice = orderDetails.ProductPrice;
            od.ProductQuantity = prodqty;
            if (od.ProductQuantity <= product.ProductQuantity)
            {
                if (od.ProductQuantity > orderDetails.ProductQuantity)
                {
                    product.ProductQuantity -= (od.ProductQuantity - orderDetails.ProductQuantity);
                    daprod.UpdateProduct(product);
                    this.Entities.Entry(orderDetails).CurrentValues.SetValues(od);
                    this.Entities.SaveChanges();
                }
                else if (od.ProductQuantity < orderDetails.ProductQuantity)
                {
                    product.ProductQuantity += (orderDetails.ProductQuantity - od.ProductQuantity);
                    daprod.UpdateProduct(product);
                    this.Entities.Entry(orderDetails).CurrentValues.SetValues(od);
                    this.Entities.SaveChanges();
                }
            }
        else
        {
            throw new Exception("Stock is too low");
        }
    }

这就是错误显示在“this.Entities.SaveChanges();”

public void UpdateProduct(CommonLayer.PRODUCT product)
    {
        CommonLayer.PRODUCT ExistingProduct = this.GetProduct(product.ProductId);
        this.Entities.Entry(ExistingProduct).CurrentValues.SetValues(product);
        this.Entities.SaveChanges();
    }

任何帮助都会非常感激,因为我似乎无法找到解决此错误的方法。谢谢!

2 个答案:

答案 0 :(得分:0)

一个好的做法是在控制器中放入开始,保存/回滚事务,以避免在核心函数SaveChanges和{{1}中执行UpdateProduct次调用的多个实例..} ..触发了线程异常

尝试此操作,删除核心功能UpdateOrderDetailsSaveChanges上的所有现有UpdateProduct来电,并将其置于您的控制器中

UpdateOrderDetails

在这里,您可以看到您可以检测到记录是否已正确保存,在这种情况下您可以将其提交到数据库,否则您只需回滚事务

所有这些片段作为评论可以根据您声明实体的方式而有所不同,但这应该有助于解决您的问题,同时遵循在MVC中使用事务的良好实践

答案 1 :(得分:0)

天上。我认为你太过于重复使用你的实体了。尝试为您使用的每笔交易初始化新的上下文...执行此操作(同样,从SaveChanges函数中删除UpdateProduct,这样您只需拨打SaveChanges一次...试试这个在if-else-if阻止

之前
using(var context = new CommonLayer.DBModelEntities()){
 if (od.ProductQuantity > orderDetails.ProductQuantity)
 {
   product.ProductQuantity -= (od.ProductQuantity - orderDetails.ProductQuantity);
   daprod.UpdateProduct(product, context);
   context.Entry(orderDetails).CurrentValues.SetValues(od);
 }
 else if (od.ProductQuantity < orderDetails.ProductQuantity)
 {
    product.ProductQuantity += (orderDetails.ProductQuantity - od.ProductQuantity);
    daprod.UpdateProduct(product, context);
    context.Entry(orderDetails).CurrentValues.SetValues(od);
 }

 context.SaveChanges();
}

有了这个,您还应该更改UpdateProduct函数以接收您正在使用的当前数据库上下文

public void UpdateProduct(CommonLayer.PRODUCT product, CommonLayer.DBModelEntities context)
{
  CommonLayer.PRODUCT ExistingProduct = this.GetProduct(product.ProductId);
  context.Entry(ExistingProduct).CurrentValues.SetValues(product);
}