Delphi 10.4.2,FireDac 连接到 Informix,隔离级别
Delphi 10.4.2 , FireDac Connecting to Informix , Isolation Level
到目前为止,我一直在使用 Isolation xiDirtyRead,效果非常好。但不幸的是有时有些项目被删除,原因是远程行有时有不正确的数据。
我用谷歌搜索,看起来显而易见的解决方案是简单地将其设置为 xiReadCommited 。但我开始对此感到困惑。
根据此页面:Committed Read Isolation 它不锁定并且几乎与 xiDirtyRead(或读未提交)一样快。它还说它实际上并没有放置完美的锁,因为我在任何情况下都不能阻止对数据库的任何操作。
但就在文字之后
In the Committed Read isolation level, locks held by other sessions
can cause SQL operations to fail if the current session cannot acquire
a lock or if the database server detects a deadlock. (A deadlock
occurs when two users hold locks, and each user wants to acquire a
lock that the other user owns.) The LAST COMMITTED keyword option to
the SET ISOLATION COMMITTED READ statement of SQL reduces the risk of
locking conflicts.
我这辈子都不懂,抱歉。这是什么意思?
示例:我打开一个有 16.000 行的 table,我逐行浏览这个 table
在 table 中移动,数据库检查当前行是否被锁定,如果是,我得到一个异常?
如果是,很好,如果它只是继续并且 returns 提交了 15980 行(并跳过 20 locked/uncommitted),则很糟糕。
如果如上所述发生死锁,因为我只是 ReadingCommited,这意味着我是被杀死的人,而不是另一个实际上具有完全 read/write 访问权限的进程。
谢谢。
Informix 使用锁来解决并发(其他数据库,如 PostgreSQL 用户多版本并发控制)。这意味着每次在事务中更改一行时,它将被锁定,直到事务提交或回滚。
在 Informix 中脏读隔离将忽略锁并读取具有未提交数据的行。
Committed Read 将只读取已提交的数据,如果遇到锁定的行(未提交的数据),它将:
- 如果 LOCK WAIT 设置为“NOT WAIT”,则立即中止。
- 如果 LOCK WAIT 设置为某个正值(以秒为单位),则等待释放锁。
如果“提交读取”由于锁定而中止,它只会 return 它找到的行,直到导致它中止的锁定行。
COMMITTED READ LAST COMMITTED 只会读取已提交的数据,当遇到锁定的行(未提交的数据)时,它将:
- 如果是新行 ( INSERT ),它将忽略该行。
- 如果它是更新的行 (UPDATE),它将 return 更新前该行的值(最后提交的数据)。
- 如果它是已删除的行 (DELETE),它将 return 删除前该行的值(最后提交的数据)。
请注意,即使使用 COMMITTED READ 隔离级别,在您阅读它们后 table 中的行也可能会更改。
到目前为止,我一直在使用 Isolation xiDirtyRead,效果非常好。但不幸的是有时有些项目被删除,原因是远程行有时有不正确的数据。
我用谷歌搜索,看起来显而易见的解决方案是简单地将其设置为 xiReadCommited 。但我开始对此感到困惑。
根据此页面:Committed Read Isolation 它不锁定并且几乎与 xiDirtyRead(或读未提交)一样快。它还说它实际上并没有放置完美的锁,因为我在任何情况下都不能阻止对数据库的任何操作。
但就在文字之后
In the Committed Read isolation level, locks held by other sessions can cause SQL operations to fail if the current session cannot acquire a lock or if the database server detects a deadlock. (A deadlock occurs when two users hold locks, and each user wants to acquire a lock that the other user owns.) The LAST COMMITTED keyword option to the SET ISOLATION COMMITTED READ statement of SQL reduces the risk of locking conflicts.
我这辈子都不懂,抱歉。这是什么意思?
示例:我打开一个有 16.000 行的 table,我逐行浏览这个 table 在 table 中移动,数据库检查当前行是否被锁定,如果是,我得到一个异常?
如果是,很好,如果它只是继续并且 returns 提交了 15980 行(并跳过 20 locked/uncommitted),则很糟糕。
如果如上所述发生死锁,因为我只是 ReadingCommited,这意味着我是被杀死的人,而不是另一个实际上具有完全 read/write 访问权限的进程。
谢谢。
Informix 使用锁来解决并发(其他数据库,如 PostgreSQL 用户多版本并发控制)。这意味着每次在事务中更改一行时,它将被锁定,直到事务提交或回滚。
在 Informix 中脏读隔离将忽略锁并读取具有未提交数据的行。
Committed Read 将只读取已提交的数据,如果遇到锁定的行(未提交的数据),它将:
- 如果 LOCK WAIT 设置为“NOT WAIT”,则立即中止。
- 如果 LOCK WAIT 设置为某个正值(以秒为单位),则等待释放锁。
如果“提交读取”由于锁定而中止,它只会 return 它找到的行,直到导致它中止的锁定行。
COMMITTED READ LAST COMMITTED 只会读取已提交的数据,当遇到锁定的行(未提交的数据)时,它将:
- 如果是新行 ( INSERT ),它将忽略该行。
- 如果它是更新的行 (UPDATE),它将 return 更新前该行的值(最后提交的数据)。
- 如果它是已删除的行 (DELETE),它将 return 删除前该行的值(最后提交的数据)。
请注意,即使使用 COMMITTED READ 隔离级别,在您阅读它们后 table 中的行也可能会更改。