如何保证数据一致性
c# 应用程序。
我正在执行选择,然后更新表中的列。我将它们放在一个单独的事务中,并将隔离级别设置为可序列化。我这样做是为了实现数据一致性。
但我仍然可以检查多个用户是否能够读取(选择)相同的值并最终尝试使用相同的值进行更新。
任何人都可以建议我如何实现一致性,以便
没有两个用户读取相同的值。
没有用户读取已更新但尚未提交的值。
c# application.
I am doing a select followed by update of a column in a table. I am putting these in a separate transaction with isolation level set to Serializable. I am doing this to achieve data consistency.
But still I can check that multiple users are able to read (select) the same value and eventually trying to update with the same value.
Can anyone suggest how i can achieve consistency, such that
No two users read the same value.
No user read a value which is updated but not yet committed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您想防止这种情况,则称为悲观锁定。您可以使用(表|行)锁来做到这一点,但这会降低您的性能。
“标准”方法是使用乐观并发并在问题发生后解决问题。
您可以(仅)通过一次仅允许 1 个连接来确保这一点。
这只需要(更轻的)ReadCommited 隔离级别。
If you want to prevent this it's called pessimistic locking. You can do this with (Table|Row) locks but it will kill your performance.
The 'standard' way is to use optimistic concurrency and solve the problem after it has happened.
You can (only) assure this by allowing only 1 connection at a time.
That only requires the (much lighter) ReadCommitted isolation level.
我认为您指的是并发。如果您要问的是这个问题,请查看链接以开始理解它。根据您的后端和具体情况,您可能需要做更多的研究。同样,如果这就是您正在寻找的内容,您可能会对悲观并发特别感兴趣。
http://en.wikipedia.org/wiki/Concurrency_control
处理 .NET 中的并发问题
I think you are referring to Concurrency. Check out the link to get started on understanding it, if that is what you are asking about. You will probably have to do a little more research depending on your back end and your specific situation. Again, if this is what you are looking for you may be particullary interested in pessimistic concurrency.
http://en.wikipedia.org/wiki/Concurrency_control
Handling Concurrency Issues in .NET
有很多不同的方法可以实现这一目标。您可以在记录上使用时间戳。当您进行更新时,请确保 ID 匹配,并且应用程序提取的记录与时间戳匹配。
为了避免用户读取未提交的记录,请查看在查询中使用 sql 提示。
There are a lot of different ways to achieve this. You can use timestamps on your records. When you do an update you make sure that the id matches and the timestamp that your application pulled with the record matches.
To avoid having a user read a record that is uncommitted look at using sql hints in your queries.
完成任务的一种方法:
您必须在表中添加一个“锁定”字段。
那么你应该编写一个存储过程,它将一些 ID 作为参数,原子地选择带有 NULL 锁的行,更新该行,以便锁包含传递的 id,然后返回该值。
只要存储过程以原子方式执行(对该表的任何其他请求都将等待,直到该请求完成),调用此过程的每个客户端都将获得另一个其锁定字段仍为空的值。一旦返回该值,客户端就确信包含该值的行已将其锁定字段设置为某个值,并且不会返回该值。
进行修改后,您应该更新该行,写入新值并将锁定字段设置为 NULL,从而为将来的请求“解锁”该行。
one way to accomplish the task:
you will have to add a "lock" field to your table.
then you should write a stored procedure that will take some ID as a parameter, atomically select a row with NULL lock, update the row so that lock will contain the passed id and then return the value.
As long as the stored procedure is executed atomically (any other requests for the table will wait until this one is finished) every client calling this procedure will get another value that still had it's lock field empty. Once the value is returned client is confident that the row containing the value has its lock field set to some value an will not be returned.
After you do modifications you should update the row, writing the new value and setting the lock field to NULL, thus "unlocking" the row for future requests.
如何将更新放入 stroed 过程中返回并从我的应用程序中调用它。
这能解决所有问题吗?
How about putting a update with returning in a stroed proc and calling it from my application.
Will this take care of all the problems?
没有两个用户读取相同的值。
为此,请在 SET TRANSACTION 语句中添加 RESERVING mytable FOR PROTECTED WRITE(或数据库上的本地等效项)。
没有用户读取已更新但尚未提交的值。
如果您使用 SERIALIZABLE 事务,则不会遇到此问题。
No two users read the same value.
To do this, in your SET TRANSACTION statement, add RESERVING mytable FOR PROTECTED WRITE (or the local equivalent on your database).
No user read a value which is updated but not yet committed.
If you are using SERIALIZABLE transactions you won't have this problem.