即使我已TransactionScope
,我也无法在数据表上实现同步数据访问。
我有一个WCF服务,负责访问存储在SQL数据库中的序列化对象图;这是通过一个名为GetObject
的操作契约实现的,它使用给定的tokenId
从表中返回一个序列化对象。 tokenId在我们的场景中是相关的,以确保在任何时间点没有两个用户可以访问同一行(对象图)。
说到wcf服务,我们的服务是多线程的(Cuncurrency
是Multiple
而InstanceContextMode
是PerCall
)。
public CustomObject GetObject(string username, string userTeam)
{
int tokenID = Database.GetNextToken(username, userTeam);
MainDataLayer.LoadData loadData = new MainDataLayer.LoadData();
return loadData.GetObject (tokenID);
}
GetNextToken(tokenID)
调用CLR stored procedure
来访问事务范围内的数据库表。
public static void usp_GetNextToken(SqlString userID, SqlString userTeam)
{
using (TransactionScope transactionScope = new TransactionScope())
{
using (SqlConnection connection = new SqlConnection("context connection = true"))
{
connection.Open();
SqlDataRecord record = new SqlDataRecord(new SqlMetaData[1]
{
new SqlMetaData("objectId", SqlDbType.Int)
});
SqlDataAdapter sqlDataAdapter2 = new SqlDataAdapter(new SqlCommand("SELECT top (1) * FROM myTable where lockedby= ' ' ORDER BY createdate DESC ", connection));
DataSet dataSet2 = new DataSet();
if (connection.State == ConnectionState.Closed)
connection.Open();
((DataAdapter) sqlDataAdapter2).Fill(dataSet2);
if (dataSet2.Tables[0].Rows.Count > 0)
{
new SqlCommand(string.Concat(new object[4]
{
(object) "UPDATE myTable SET lockedby = '",
(object) userID.ToString(),
(object) "' WHERE objectId = ",
(object) int.Parse(dataSet2.Tables[0].Rows[0][" objectId "].ToString())
}), connection).ExecuteNonQuery();
record.SetSqlInt32(0, (SqlInt32) int.Parse(dataSet2.Tables[0].Rows[0][" objectId "].ToString()));
SqlContext.Pipe.Send(record);
return;
}
}
record.SetSqlInt32(0, (SqlInt32) 0);
SqlContext.Pipe.Send(record);
}
transactionScope.Complete();
}
}
问题 完成所有这些后,我们在大多数情况下最终会让多个用户访问相同的对象图。
答案 0 :(得分:0)
不确定你想要在这里实现什么。 TransactionScope仅在适当位置,因此您可以提交或回滚SQL语句。
我认为你可以使用lock
来防止多个请求被handeld:
private static object DatabaseLock = new object();
public CustomObject GetObject(string username, string userTeam)
{
lock (DatabaseLock)
{
int tokenID = Database.GetNextToken(username, userTeam);
MainDataLayer.LoadData loadData = new MainDataLayer.LoadData();
return loadData.GetObject (tokenID);
}
}
然而,这会影响表现。
创建Concurrency
设置为Single
的服务并不简单吗?