lee*_*d00 5 mysql postgresql sql-server data-versioning
Oracle 以外的其他数据库是否有ora_rowscn
(http://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns007.htm)等价物,或者您是否必须在您的字段、代码和存储过程中自己实现它们?
ora_rowscn
是附加到使用某些特定设置创建的 Oracle 中所有表的伪列,在执行乐观离线锁定时使用。
据我了解这个问题,这种情况是用户从事务外部的数据库读取值,然后尝试更新。要求是数据库检测何时可能发生丢失更新。
SQL Server 不提供 Oracle 伪列的直接等效项,ora_rowscn
因为它并不专门使用行版本控制来实现事务隔离级别(因此行版本控制信息并不总是存在)。尽管如此,有多种方法可以使用 SQL Server 实现乐观并发控制。
一种选择是向表中添加一rowversion
列。通常,该列在所有表中都会被赋予相同的名称(例如RV
)。一般的策略是在读取数据时读取该rowversion
值,并在稍后更新该行时检查该值是否未更改:
CREATE TABLE dbo.Example
(
SomeKey integer PRIMARY KEY,
SomeValue integer NOT NULL,
OtherValue integer NOT NULL,
RV rowversion NOT NULL
);
INSERT dbo.Example
(SomeKey, SomeValue, OtherValue)
VALUES
(1, 100, 1000);
-- Read data
SELECT SomeValue, RV
FROM dbo.Example AS E
WHERE SomeKey = 1;
-- Time passes
-- Attempt update
UPDATE dbo.Example
SET SomeValue = 123
WHERE SomeKey = 1
AND RV = 0x0000000000273711;
Run Code Online (Sandbox Code Playgroud)
如果该行已被修改,则该UPDATE
语句不会进行任何更改,并且不会返回任何错误或警告。由开发人员检查受该语句影响的行数,并采取适当的操作(例如重新读取源行,并警告用户存在冲突)。
服务器端游标经常用于我们正在讨论的场景中。SQL ServerOPTIMISTIC
通过许多接口(例如API、ODBC、Native Client)包含对服务器端游标的本机支持。如果rowversion
存在列,SQL Server 将使用它来实现乐观并发,而开发人员无需rowversion
显式检索和检查该值。使用Transact-SQL
光标来演示:
DECLARE UIcursor
CURSOR GLOBAL
SCROLL DYNAMIC
OPTIMISTIC
FOR
SELECT SomeValue
FROM dbo.Example
WHERE SomeKey = 1
FOR UPDATE OF SomeValue;
OPEN UIcursor;
-- Read data
FETCH FIRST FROM UIcursor;
-- Time passes
-- Attempt update (note no rowversion reference needed)
UPDATE dbo.Example
SET SomeValue = 321
WHERE CURRENT OF UIcursor;
Run Code Online (Sandbox Code Playgroud)
如果自读取数据后该行已更改,则会返回警告和错误:
CREATE TABLE dbo.Example
(
SomeKey integer PRIMARY KEY,
SomeValue integer NOT NULL,
OtherValue integer NOT NULL,
RV rowversion NOT NULL
);
INSERT dbo.Example
(SomeKey, SomeValue, OtherValue)
VALUES
(1, 100, 1000);
-- Read data
SELECT SomeValue, RV
FROM dbo.Example AS E
WHERE SomeKey = 1;
-- Time passes
-- Attempt update
UPDATE dbo.Example
SET SomeValue = 123
WHERE SomeKey = 1
AND RV = 0x0000000000273711;
Run Code Online (Sandbox Code Playgroud)
如果表不包含rowversion
,SQL Server 会透明地使用可靠的校验和来检测行更改。如果校验和比较失败,则会生成相同的警告和错误。使用rowversion
比使用内部校验和更有效,但两者同样可靠。
请注意,真正的实现不太可能使用如上所示的全局 Transact-SQL 游标,但使用开发框架中可用的任何服务器端游标支持时,概念是相同的。
归档时间: |
|
查看次数: |
3150 次 |
最近记录: |