5

I know the difference between Data Reader and Data Set.

The DataReader is a better choice for applications that require optimized read-only, fast and forward-only data access.

The Data set is better for Application wherein you can get all the data and update it according to your needs at application level and submit the change to the database.

Please clear if there is anything wrong in my understanding.

Now I had an interview there a person asked me. Is datareader or Connected architecture good for application like ticketing system. Basically she meant were many user might be trying to update the same table. Thus the concept of Concurrency comes.

We can Use Disconnected architecture to check for concurrency and let only one user update the table at a time. But dont know how it happens in terms of connected Architecture. Does the connection to the data base and particularly to the table concerned would that make only one user do the update while others who try to hit later wont be able to do that.

Wont it affect the performance if all the user have opened a connection as database will reach bottle neck.

I hope i will get the answer to understand them.

4

1 回答 1

4

我认为这不是哪个更好的问题,因为数据一旦到达客户端就已经是旧的/无效的。显示预订表有助于粗略了解预订的情况,但下一秒可能会完全不同。你想消除竞争条件。一个好的架构是必要的。

一种方法是“预订”票 [1]。应用程序要求获取在匹配标准的情况下可用的票证。在这一点上,关于票是否可用是一个已知的事实。如果它可用,它也已被保留。这避免了一张票的多次预订。下一次预订(相同的操作/操作)将导致预订不同的票。如果需要,您可以随时在此票证中添加信息(例如票证所有者及其信息)。没有附加信息的票证将在一定分钟后超时并返回到池中。这些票可以再次“保留”[1]。

[1] 为避免多次赋值,请使用乐观锁定

要回答这个问题,我会说DataReader。它将数据库通信保持在最低限度(负载和锁定),因此它可以尽快处理更新。请记住,选择一个并不能解决并发问题。重要的是整体解决方案。

例子

我不知道要求,但因为这是一个面试问题,我会举一个例子。不要将此视为黄金法则,但在我的脑海中,它会是这样的:

(如果需要)首先向用户显示一个屏幕,显示系统中还有可以预订的票。打开一个连接,并通过一个阅读器读取可供预订的门票数量。关闭阅读器和连接。用户进入下一个屏幕。

SELECT COUNT(*)
FROM [Tickets]
WHERE ([LastReserved] IS NULL OR [LastReserved] <= DATEADD(MINUTE, GETDATE(), @ticketTimeout))
    AND [TickedAssignedToUserId] IS NULL;

用户请求 x 数量的票并进入下一个屏幕。此时系统会通过乐观锁定检查是否有足够的票证可用。只需打开一个连接(使用事务!)并执行以下查询:

UPDATE TOP(@numberOfTicketsRequested) [Tickets]
SET [LastReserved]=GETDATE()
WHERE ([LastReserved] IS NULL OR [LastReserved] <= DATEADD(MINUTE, GETDATE(), @ticketTimeout))
    AND [TickedAssignedToUserId] IS NULL;

受影响的行数应与@numberOfTicketsRequested 相同。如果是这种情况,请提交事务并获取它的票证标识符。否则回滚并告诉用户不再有可用的票证。此时我们需要记录信息,因此您可能还想获取标识符。

此时,用户有@ticketTimeout几分钟的时间来输入他们的用户详细信息。如果正确完成,可以执行以下查询:

UPDATE TOP(@numberOfTicketsRequested) [Tickets]
SET [TickedAssignedToUserId]=@userId
WHERE [TicketId]=@Id AND [LastReserved]=@lastReserved AND [TickedAssignedToUserId] IS NULL;

如果用户花费的时间超过 10 分钟,并且其他人再次请求了同一张票,则LastReserved时间戳已更改。当第一个用户尝试使用他们的详细信息预订票时,更新不再与原始LastReserved时间戳匹配,并且更新将显示没有足够的行受到影响(=回滚)。如果它与受影响的行数匹配,则用户成功保留票证 (=commit)。

请注意,除了票证标识符之外,没有票证信息到达应用程序。我也没有包括用户注册。没有完整的表被传递,并且锁只是被最低限度地使用(仅用于两个短暂的更新)。

于 2013-06-09T12:41:02.020 回答