我有一个用C#.NET编写的应用程序,用户输入,编辑和删除访问使用SQL Server创建的数据库的事件。应用程序使用搜索页面将搜索查询中的各行填充到数据网格中,然后一旦选择,用户就可以按下更新按钮,而更新按钮又转到另一个页面,其中数据被填充到一个表格中进行编辑,这是我的问题在哪里。我正在尝试实现一种锁定机制,以便当用户从数据库访问一行时,另一个用户将无法启动同一页面。目前我已经为页面调用的每个存储过程实现了几个事务,这些事务可以解决这个问题,但是,当页面加载时,每个存储过程都被单独调用,然后在填充数据后关闭,所以没有办法通过那里锁定。这是我的下一个想法,试图在此特定页面加载时将其锁定到并发用户。填充页面的主存储过程调用IncidentID来检索数据,那么有没有办法检查是否在Page_Load中使用了此ID?我仍处于入门级别,肩膀上有一个巨大的头部,所以我正在通过这里和其他网页学习很多这个实现,但我还没有找到任何帮助......但代码相当冗长但如果您需要参考,请告诉我。 TIA
编辑:这是一些代码。我正在使用SSMS,因此为我添加了分号。这些是测试,但具有确切的语法...... 查询以使用数据填充表单
USE [Test_Live]
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_SelectIncident_ByCaseNumberUpdate]
(
@IncidentID int
)
AS
BEGIN TRANSACTION
SELECT i.IncidentID,
i.PersonID,
i.BusInfoID,
i.TypeOfIncident,
i.DateOfIncident,
/* etc. etc. */
FROM tblTestIncident i WITH(ROWLOCK)
left JOIN tblTestPerson p on i.PersonID = p.PersonID
/* some other joins are here */
WHERE i.IncidentID = @IncidentID
COMMIT
用数据填充表单的C#代码。 GetConnection()方法位于页面正在使用的另一个.dll文件中。它通过ConfigurationSettings.AppSettings返回连接字符串。
protected void Page_Load(object sender, EventArgs e)
{
this.gIncidentID = Convert.ToInt32(Utils.decryptQueryString(this.Request.QueryString["iid"]));
try
{
this.lblCurrentUser.Text = this.Page.User.Identity.Name.ToUpper();
}
catch (Exception ex)
{
this.lblErrors.Text = this.lblErrors.Text + "Unexpected exception in Load: " + ex.Message + ". ";
}
this.populateFormWithData(this.gIncidentID);
}
private void populateFormWithData(int incidentID)
{
SqlConnection connection = this.GetConnection();
SqlParameter sqlParameter = new SqlParameter("@IncidentID", SqlDbType.Int);
sqlParameter.Direction = ParameterDirection.Input;
sqlParameter.Value = (object)incidentID;
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
sqlDataAdapter.SelectCommand = new SqlCommand();
DataSet dataSet = new DataSet();
sqlDataAdapter.SelectCommand.Connection = connection;
sqlDataAdapter.SelectCommand.CommandText = "sp_SelectIncident_ByCaseNumberUpdate";
sqlDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure;
sqlDataAdapter.SelectCommand.Parameters.Add(sqlParameter);
sqlDataAdapter.Fill(dataSet, "Incident");
if (dataSet.Tables["Incident"].Rows.Count > 0)
{
//code that fills in all fields within the page
}
else
{
this.lblCaseNumberData.ForeColor.Equals((object)"Red");
this.lblCaseNumberData.Text = "No Case data found!";
}
//this is where I think the problem is as to why the transactions aren't working
connection.Close();
}
我希望这会有所帮助......
答案 0 :(得分:1)
像这样锁定数据可能会有问题。用户可以保持页面打开并离开当天。 数据将被锁定,直到它们返回。最好在表中添加TimeStamp列并在更新前检查它是否已更改。如果TimeStamp已更改,请通知用户并重新加载数据。
见这里的例子:
SQL Server optimistic locking - Returning changed timestamp value
TimeStamp / RowVersion信息:
http://msdn.microsoft.com/en-us/library/ms182776%28v=sql.105%29.aspx