Web开发数据一致性-时间戳

一、概念

     时间戳:数据库中自动生成的唯一二进制数字,与时间和日期无关的, 通常用作给表行加版本戳的机制。
     时间戳存储大小为 8 个字节。 不可为空的 timestamp 列在语义上等价于 binary(8) 列。可为空的 timestamp 列在语义上等价于 varbinary(8) 列。这将导致在C#程序中获取到的timestamp类型则变成了byte[]类型。所以如果我们需要从数据库中获取并使用这个时间戳的话就必需经过转换。
二、应用场景
     用户A、B同时打开某条记录开始编辑,当A保存编辑的信息,更新了数据库,此时,若B用户也保存了编辑的信息,那么,这次保存的信息就会覆盖A更新后的信息,到时数据不一致;
     时间戳就能很好的解决这一问题。因为数据库记录每次被更新时,系统都会自动维护时间戳,如果保存时发现取出来的时间戳与数据库中的时间戳不相等,说明在这个过程中记录被更新过,若已经被更新过,则提示重新更新数据编辑,不予保存信息,这样的话可以防止别人的更新被覆盖。

二、具体应用实例

1、数据库使用timestamp列,采用.net core的linq进行实体映射
     直接保存到前端,提交信息后直接比较时间戳是否一致,即可判断正在编辑的数据是否被改过。

**数据库端:**
	字段值:timestamp timestamp not null;(数据类型)
	
**c#实体类:**
person{
	...
	public byte[] Timestamp { get; set; }
	...
}
**前端:**
	用input直接保存timestamp的值

**control控制器:**
...
直接比较时间戳
 for(int i = 0; i < person.Timestamp.Length;i++)
                    if (person.Timestamp[i] != model.Timestamp[i])
                    {
                        resultStr = string.Format("正在编辑的编号为[{0}]的用户数据已经被更改,请重新编辑!", model.UserId);
                        return false;

                    }
...

2、用datetime做时间戳
     当数据库中保存的只有类似数据更新时间、创建时间时,可以将其作为时间戳,只需要时间转时间戳就行。
     具体思路是,将datetime值转换为long类型的值,保存在在前端,当编辑保存提交到后端,查询数据库当前的时间转换为long,然后进行比较。

伪代码:

数据库sql:
	select 
	...
CONVERT(BIGINT,DATEDIFF(MI,'1970-01-01 00:00:00.000', e.updateDate)) * 60000 + DATEPART(S,e.updateDate) * 1000 + DATEPART(MS, e.updateDate) as [timestamp]
	...




**后端:**
//转换
bool updateDate(personDtos){
	//查询数据库当前值
	Person person = _service.get(e => e.id == p.id);
	long updateTIme = DateToTicks(person.updateTIme);
	
	//比较时间戳
	if(personDtos.timestamp == updateTime){
		//数据没有被更改
	}else{
		//数据已经被更改
	}
}

//DateTime类型转换为时间戳(毫秒值)
public long DateToTicks(DateTime time)
{
  return ((time.HasValue ? time.Value.Ticks : DateTime.Parse("1990-01-01").Ticks) - 621355968000000000) / 10000;
}
 
//时间戳(毫秒值)String转换为DateTime类型转换
public DateTime TicksToDate(string time)
{
  return new DateTime((Convert.ToInt64(time) * 10000) + 621355968000000000);
}

Guess you like

Origin blog.csdn.net/psl1234554321/article/details/109044305