I have a value called x in my database and two transactions, T1 & T2. Assume both transactions use the multi-document ACID API MongoDB provides.
我的数据库中有一个名为x的值和两个事务t1和t2。假设两个事务都使用MongoDB提供的多文档ACID API。
Each transaction reads the value of x and decrements it by 1. When reading, the code checks that the value of x is greater than 0.
每个事务读取x的值并将其减1。读取时,代码检查x的值是否大于0。
Now, the value of x is 1 and T1 & T2 occur concurrently. Assume the following execution thread
现在,x的值是1,t1和t2同时发生。假设下面的执行线程
T1 reads x = 1
T2 reads x = 1
T1 writes x = 0
T2 writes x = 0
In this situation will T2 detect that the value of x that it read has been changed and abort the transaction (presumably based on some internal timestamp) or will it continue with the write?
在这种情况下,T2是否会检测到它读取的x值已更改并中止事务(假设基于某个内部时间戳),还是将继续写入?
I have tried looking through the MongoDB docs and I can't find a satisfactory explanation to this.
我试过查看MongoDB文档,我找不到一个令人满意的解释。
更多回答
优秀答案推荐
Assuming the following scenario:
假设以下场景:
transaction {
read x
if x>0 {
write x
}
}
Suppose one transaction starts and reads x=1, and the second transaction does the same and writes x. The first teansaction will fail and it will be retried. This tine it will read 0 and will not update.
假设一个事务启动并读取x=1,而第二个事务执行相同的操作并写入x。第一个teansaction将失败,并将被重试。该时间将显示为0,并且不会更新。
That is why a transaction must include all operations that affects the transaction, and it must be retryable. If you read x before starting the transaction it would overwrite.
这就是为什么一个事务必须包括影响该事务的所有操作,并且它必须是可重试的。如果在开始事务之前读取x,它将被覆盖。
That said, this scenario can be implemented using an atomic update with a filter checking x>0.
也就是说,这个场景可以使用带有过滤器检查x>0的原子更新来实现。
更多回答
Why would T1 fail even if T2 wrote first? Both of them read x=1 simultaneously. For T1, the if condition would still pass even if T2 committed because at the time T1 read x, it was still 1.
为什么即使T2先写入,T1也会失败?它们都同时读取x=1。对于T1,即使T2被提交,IF条件仍将通过,因为在T1读取x的时刻,它仍然是1。
Afaik, a read operation will not lock.
AFAIK,则读操作不会锁定。
我是一名优秀的程序员,十分优秀!