数据库表设计:用数据库版本字段控制程序的并发写操作真的过时了吗?

Mr_HShell 发布于 2015/10/13 10:38
阅读 2K+
收藏 0
如题。不知道是不是发在这个。


新人开发者一位,为系统设计表。系统用户在万以内,是内部管理软件,我以前的做法一直是为每张表设置一个数据库版本字段(Version),每次更新操作都要比较这个Version,如果版本号不匹配则说明数据已被他人修改,提示用户重新加载数据。


但是最近公司一位前辈跟我说,这种做法已经过时了,应该使用sql来控制,类似: UPDATE TABLE_A SET COLUMN_A = newValue WHERE COLUMN_A = oldValue。这样不仅可以判断并发,并且可以灵活使用,意思是:如果我想更新字段B,就算字段A被别人更新了,我也能更新B,而不会被“锁住”。


但是,我认为,应该需要保持一条数据的完整性,就算你想要修改的是没有被别人修改过的B,在这种情况下也应该被拒绝才对,因为我们不能肯定字段A的更新会不会影响用户对B字段更新的判断。


我想知道,目前这种程序更新的小并发控制是如何体现到表设计上的。


不知道自己表述的够不够清楚,请各位前辈指教。
加载中
0
气质舞王尼古拉斯赵四
气质舞王尼古拉斯赵四
你考虑的这些事情是dbms的活吧
0
M
Mr_HShell

引用来自“春天花不开”的评论

你考虑的这些事情是dbms的活吧
并不是吧?我目前在设计系统表,我就想知道应用系统中如果不用字段判别数据版本,那如何排除并发操作呢?
0
jolphin
jolphin
这两种都是属于乐观锁,作用是一样的
0
M
Mr_HShell

引用来自“jolphin”的评论

这两种都是属于乐观锁,作用是一样的

我的前辈的意思是用Version控制过时了,我想向社区的各位了解下,真的过时了吗?

并且我不觉得我前辈的那种做法是正确的,我是站在数据完整性的角度上考虑,我这样认为,对吗?

M
Mr_HShell
我想明白了,我的想法是:最小原子到行,我前辈的想法是:最小原子到列。但我还是认为行锁是比较正确的想法。
jolphin
jolphin
两种都可以用,从数据完整性来说也没什么问题,毕竟数据库锁的最小粒度是行锁,所以跟更新几个字段没什么关系。
0
jQer
jQer
你这种版本控制,断电了怎么办?现代数据库,都是内置版本控制.你应该使用提供的事务编程接口,而不是自己去实现.
M
Mr_HShell
你指的什么断电?客户端?数据库? 你的意思是,数据版本控制应该交由数据库去管理(数据库编程),程序中的更新操作全部使用数据库提供的更新事务接口来做,是吗?
0
M
Mr_HShell

引用来自“jQer”的评论

你这种版本控制,断电了怎么办?现代数据库,都是内置版本控制.你应该使用提供的事务编程接口,而不是自己去实现.

你指的什么断电?客户端?数据库?

你的意思是,数据版本控制应该交由数据库去管理(数据库编程),程序中的更新操作全部使用数据库提供的更新事务接口来做,是吗?

jQer
jQer
0
GameKing
GameKing
version的方式应该好一点
0
打怪兽的汪
打怪兽的汪
你不觉得多人能同时修改某一数据这个系统本身就有问题,撇开这个不说,一定要实现的话我会选择你同事的做法!
M
Mr_HShell
多个拥有相同权限的用户修改同一条数据的可能性是存在的啊?两种都可以,我只是一只觉得数据的原子性应该是行,如果是我同事的想法,那么对程序编码来说,更新编码需要根据业务做预判,哪几个字段会影响用户对这个数据的更新,这样对抽象底层操作来说,非常不便啊
0
仪山湖
仪山湖
数据库本身自带事务,事务诞生的目的就是为了解决并发,避免不一致的写。应该多了解事务的运作机制、用途及使用方法。
0
iyo想静静
iyo想静静

单纯从描述看,第2种方式不能满足以下场景:

假设存在表T(a,b),a、b是2个字段,当前值a=11、b=22。

如果存在并发写操作甲、乙:

甲:update T t set t.b=222 where t.b = 22,先于乙提交成功到数据库了,这时

a=11,b=222,然后

乙:  update T t set t.a=111 where t.a = 11,也会成功执行,这时

a=111、b=222,

但对于甲来说,它的希望结果可能是a=11、b=222。

但对于乙来说,它的希望结果可能是a=111、b=22。

两边都不满足了。

如果通过第1种方式控制,在甲提交成功后,就会把乙踢掉。

个人看法,供参考。


返回顶部
顶部