Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 举例来说,在SQLServer中时间戳列的实际用途是什么?_Sql Server - Fatal编程技术网

Sql server 举例来说,在SQLServer中时间戳列的实际用途是什么?

Sql server 举例来说,在SQLServer中时间戳列的实际用途是什么?,sql-server,Sql Server,我在sql server中遇到了时间戳数据类型。通过示例,sql server中时间戳列的实际用途是什么?让我们以销售订单表为例来说明时间戳的作用 create table saleorder (ordernumber int, amount int, timestamp); insert into saleorder (ordernumber, amount) values (1, 100), (2, 100), (3, 200); select * from saleorder 请注意ti

我在sql server中遇到了时间戳数据类型。通过示例,sql server中时间戳列的实际用途是什么?

让我们以销售订单表为例来说明时间戳的作用

create table saleorder (ordernumber int, amount int, timestamp);
insert into saleorder (ordernumber, amount) values (1, 100), (2, 100), (3, 200);
select * from saleorder
请注意timestamp列中的数据。(SQL Server 2005)表示:此(即时间戳)跟踪数据库中的相对时间,而不是可以与时钟关联的实际时间…每次修改或插入带有时间戳列的行时,都会在时间戳列中插入递增的数据库时间戳值

让我们看看数据是什么样子的:

ordernumber amount  timestamp
1           100     0x00000000000007D1
2           100     0x00000000000007D2
3           200     0x00000000000007D3
好的。订单1首先添加,订单3最后输入。如果我们要更新订单1的数量,会发生什么

update saleorder set amount = 200 where ordernumber = 1
select * from saleorder
啊,注意订单1的时间戳现在是0x7D4(十进制2004)。相对于其他行,我们知道order 1是最近更新的。但是,更重要的是,当并发写入发生时,时间戳的值就出现了

ordernumber amount  timestamp
1           200     0x00000000000007D4
2           100     0x00000000000007D2
3           200     0x00000000000007D3
假设John和Mary都在销售部,使用在.NET中开发的web应用程序处理订单3。约翰调出订单进行更改。约翰还没有保存数据。玛丽也按同样的顺序做了改变。约翰先救。玛丽试图保存数据。NET应用程序可以首先查看Mary提取的时间戳是否仍然与数据库对order 3的时间戳相同

如果Mary使用订单3提取的时间戳现在不同了(因为John保存了数据,时间戳自动更改),则.NET应用程序可以提醒Mary并要求她刷新屏幕上的记录以查看最新的更改(或者可能突出显示屏幕上的更改)


将时间戳视为行版本。有趣的是,SQLServer的最新版本使用rowversion数据类型,它与时间戳数据类型同义。(SQL Server 2012)有一些有趣的例子。

我使用时间戳列跟踪数据更改的时间,特别是需要同步到一个或多个移动应用程序的数据。您可以使用timestamp列返回自某个时间点以来已更改的行(通过提供上一个时间戳)。

我使用了
timestamp
数据类型(
ROWVERSION
,SQL2005+)来避免:

丢失更新问题:第二个事务写入第二个值 一个数据项(数据),位于由第一个数据源写入的第一个值的顶部 并发事务,并且第一个值将丢失给其他 并发运行的事务,根据其优先级,需要 读取第一个值。读取错误值的事务 以错误的结果结束

示例:
丢失更新

t  : User 1 read payment order (PO) #1 (amount 1000)
t+1: User 2 read payment order (PO) #1 (amount 1000)

t+2: User 1 change the amount for PO #1 to 1005
t+3: User 2 change the amount for PO #1 to 1009 (change make by User 1 is lost because is overwritten by change make by User 2)
t+4: The amount is **1009**.
t  : User 1 read payment order (PO) #1 (amount 1000, timestamp 0x00000000000007D1)
t+1: User 2 read payment order (PO) #1 (amount 1000, timestamp 0x00000000000007D1)

t+2: User 1 change the amount for PO #1 to 1005 and it checks if row has the same `timestamp` (column `RW` in this case; 0x00000000000007D1). The check succeeds and the change is `COMMIT`ed. This will change, also, the timestamp (column 'RW'). The new timestamp is 0x00000000000007D4.
t+3: User 2 change the amount for PO #1 to 1009 and it checks if row has the same `timestamp` (column `RW` in this case; 0x00000000000007D4). The checks fails because the initial timestamp (@rw=0x00000000000007D1) is <> than current timestamp (column `RW`=0x00000000000007D4). An error is raised the catch block "intercepts" the error and this transaction is cancelled (`ROLLBACK`).
t+4: The amount {remains|is} **1005**.
示例:如何防止
更新丢失

t  : User 1 read payment order (PO) #1 (amount 1000)
t+1: User 2 read payment order (PO) #1 (amount 1000)

t+2: User 1 change the amount for PO #1 to 1005
t+3: User 2 change the amount for PO #1 to 1009 (change make by User 1 is lost because is overwritten by change make by User 2)
t+4: The amount is **1009**.
t  : User 1 read payment order (PO) #1 (amount 1000, timestamp 0x00000000000007D1)
t+1: User 2 read payment order (PO) #1 (amount 1000, timestamp 0x00000000000007D1)

t+2: User 1 change the amount for PO #1 to 1005 and it checks if row has the same `timestamp` (column `RW` in this case; 0x00000000000007D1). The check succeeds and the change is `COMMIT`ed. This will change, also, the timestamp (column 'RW'). The new timestamp is 0x00000000000007D4.
t+3: User 2 change the amount for PO #1 to 1009 and it checks if row has the same `timestamp` (column `RW` in this case; 0x00000000000007D4). The checks fails because the initial timestamp (@rw=0x00000000000007D1) is <> than current timestamp (column `RW`=0x00000000000007D4). An error is raised the catch block "intercepts" the error and this transaction is cancelled (`ROLLBACK`).
t+4: The amount {remains|is} **1005**.
用户1的结果(金额1000->1005):

PaymentOrderID PaymentOrderDate金额RW
-------------- ---------------- --------------------------------------- ------------------
1 2013-07-21 1000.00 0x00000000000007D1
@@行计数(1009):

PaymentOrderID PaymentOrderDate金额RW
-------------- ---------------- --------------------------------------- ------------------
1 2013-07-21 1000.00 0x00000000000007D1

@@ROWCOUNT第二个输出列表中ordernumber 1的金额值需要更改为200。@ulty4life-sharp eyes!我已经做了更新。感谢您的改进。为什么DateTime不是驱动此警报的适当机制?(不是一个修辞性的问题——真正的问题,因为我不熟悉时间戳)+1.这是个好问题!如果并发处理得好,DateTime和增加版本号也是驱动此警报的好方法。请参阅此答案以了解更多关于它的讨论:修改的日期不足以避免丢失的更新问题?@Imad:这可能是一个解决方案,但开发人员应小心更新此列(
[Modified date]
)。
时间戳
/
行版本
列具有与之相同的大+,当连接执行
更新
语句时,SQL Server数据库引擎会自动更新该列。这也称为乐观并发锁定。这与另一个正确的解决方案相反:a)
开始交易
b)
选择可重复读取
以确保没有人可以更改金额c)
更新金额
d)
提交交易
。SQL Server有一个非常强大的锁定系统,人们可以利用这些功能,以正确的方式使用它们。
PaymentOrderID PaymentOrderDate Amount                                  RW
-------------- ---------------- --------------------------------------- ------------------
1              2013-07-21       1000.00                                 0x00000000000007D1

@@ROWCOUNT <- Timestamp check fails 
-----------
0

Msg 50000, Level 16, State 1, Line 27
Lost update.
PaymentOrderID PaymentOrderDate Amount                                  RW
-------------- ---------------- --------------------------------------- ------------------
1              2013-07-21       1005.00                                 0x00000000000007D4