SQL Server 事务 --- C#
我需要帮助。让我首先用一个小样本来解释一下这个场景。
假设我有一个包含列的 Students
表:
Id int(PK)
Name varchar(200)
Marks1 int
Marks2 int
Marks3 int
TotalMarks int
IsTotalCalculated bit
InProcess bit
该表有大量记录。
现在,我想计算每个学生的 TotalMarks 并更新 TotalMarks
列。
现在来到我的 C# 控制台应用程序,我正在调用存储过程:
SP1 => 我一次获取前两条记录,其中 InProcess = 0 和 IsTotalCalculated = 0,设置其 InProcess = 1 并进行处理。 (有一个 SELECT 和 UPDATE)
SP2 => 最后再次更新这两行,更新其 IsTotalCalculated = 1 和 InProcess = 0 (更新)
关注: 我的关注是一旦我选择 2 行进行处理,那么任何其他控制台应用程序实例都不应该选择这 2 行进行处理。我该怎么办?
注意:我已将两个 SP 的 C# 代码放在 TransactionBlock 中。
谢谢,
贾斯汀·塞缪尔
I need a help. Let me first explain the scenario with a small sample.
Suppose I have a Students
table with columns:
Id int(PK)
Name varchar(200)
Marks1 int
Marks2 int
Marks3 int
TotalMarks int
IsTotalCalculated bit
InProcess bit
This table has huge number of records.
Now, I want to calculate the TotalMarks of each student and update the TotalMarks
column.
Now coming to my C# Console App I am calling to stored procedures:
SP1 => I am fetching top two records at a time which has InProcess = 0 and IsTotalCalculated = 0, sets its InProcess = 1 and do the processing. (Has a SELECT and UPDATE)
SP2 => Finally again update these two rows which updates its IsTotalCalculated = 1 and InProcess = 0 (UPDATE)
Concern: My concern is as soon as I select the 2 rows for processing then any other Console App instance should not select these 2 rows for processing. What should I do?
Note: I have put the C# code of my two SPs in a TransactionBlock.
Thanks,
Justin Samuel
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
难道你不能只检查 SP1 是否 InProcess = 1 ,然后如果是 true 则忽略其余部分,直到 InProcess 变为 0 吗?
诀窍是在将 InProcess 更新为 1 时阻止任何读取。这可以通过 SET TRANSACTION ISOLATION LEVEL READ COMMITTED 来完成,该命令指定语句(在 SP 中)无法读取已被其他事务修改但未提交的数据。
希望这有帮助。
Can't you just check in SP1 if InProcess = 1 and then if that is true ignore the rest until InProcess becomes 0 ?
The trick is to block any reads while you update InProcess to 1. This can be done with SET TRANSACTION ISOLATION LEVEL READ COMMITTED which specifies that statements (in your SP) cannot read data that has been modified but not committed by other transactions.
Hope this helps.
你到底为什么要在 C# 中执行此操作?这对于 T-SQL 来说完美!
一条 T-SQL 语句就完成了,不用担心事务范围和来回洗牌数据负载......
好吧,所以如果您必须坚持当前的方法 - 您可以执行以下操作:
如何“隐藏”
Students
表,例如不允许任何人访问它,而是使用其顶部的视图,该视图仅显示 InProcess = 0 的行?这样,任何读取学生的请求将始终只读取那些当前未处理的学生。
Why on earth do you want to do this in C# ?? This is perfect for T-SQL!
One T-SQL statement and you're done, no worries about transaction scopes and shuffling loads of data back and forth.......
OK, so if you must stick to your current approach - here's what you could do:
How about "hiding" the
Students
table, e.g. not allowing anyone access to it, and instead using a view on top of it, which only ever shows the rows that have InProcess = 0?This way, any request to read students will always only read those not being processed right now.
我确信您有这样做的理由,但如果这是实际的表而不仅仅是说明性示例,那么为什么不使用带有计算总计列的视图呢?然后,您无需使用控制台应用程序处理行,也无需锁定任何行。
I'm sure you have a reason for doing things the way you are, but if this is the actual table and not just a illustrative sample then why don't you use a view with a calculated Total column? Then you have no need for processing rows with console apps, and no need to lock any rows.