求大神指点,sqlserver 数据库并发,造成数据多次更改

时间:2021-08-29 00:19:05
 数据库里用户表,有个余额字段,数字量高峰期的时候,同一秒中内同个用户余额,有时候频繁更新几十次,每次更新会插入更新明细记录表,对应的有使用数据库事物。
问题是更新结果明细只插入一条,余额有时候跟新了两次。具体原因百思不得其解,通过sqlserver Profiler也监测不出问题来,请大神指点,痛哭流涕,不慎感激 求大神指点,sqlserver 数据库并发,造成数据多次更改

16 个解决方案

#1


这个代码是不是你写的?
应该去了解为什么要这样控制数据,是不是因为业务逻辑的需要?只要它数据正确,运行符合业务逻辑要求,更新多次不是不可以。

#2


@hdhai9451  是我写的,业务是这样需求,这种状况也不是经常出现,偶尔会出现这种状况吗 
数据库并发是不是会出现这种问题

#3


那你就必须使用事务处理
betin tran
..............
....
commit tran

rollback tran

有关事务你应该了解吧,事务具有原子性、隔离性、持久性、一致性
执行代码要么全部成功,要么全部失败,使用事务再多的并发也不怕 错误


#4


求大神指点,sqlserver 数据库并发,造成数据多次更改
事务是有用上,具体没深入了解,不像是事务过程多次执行,到有点像用户余额被更新了

#5


是否执行多次,你写入日志文件不就知道了吗?
你在update语句后面加入写日志 insert into tblog(dt) values(getdate())

我认为不会执行多次的

#6


引用 4 楼 zgl_11 的回复:
求大神指点,sqlserver 数据库并发,造成数据多次更改
事务是有用上,具体没深入了解,不像是事务过程多次执行,到有点像用户余额被更新了

userinfo是记录余额的表吗?
你怎么知道执行了多次?AccountDetails中记录了相同的记录多次吗?

#7


更新不会多,只会是插入少了

这种情况,必须自己加串行化,否则更糟的事情都会发生。。。

#8


@szm341
userinfo有个保存余额的字段
 是啊,多出的金额,是之前更新的数据

#9


@hdhai9451
没有执行多次,明细只有一条,余额间断性的多出同个数据

#10


@sz_haitao
自己加入串行化是什么意思

#11


在程序无bug的前提下,有两种办法
1.提高事务的隔离级别,会降低性能
2.放弃绝对一致性,采用最终一致性;利用对账程序来对齐余额

#12


引用 8 楼 zgl_11 的回复:
@szm341
userinfo有个保存余额的字段
 是啊,多出的金额,是之前更新的数据

@在这里是没用的,需要点“引用”
其实我主要想问AccountDetails中记录了相同的记录多次吗? 
因为你的存储过程是事务模式,那么只有同时添加了记录并且成功,才会多执行一次update
如果没有这个多出来的记录,那肯定是你在执行存储过程其他的地方有操作,或者是有触发器一类比较隐蔽的操作在执行,当然也有可能有什么作业,总之肯定不会是你截图的存储过程的问题

#13


更新之前先锁表,更新后再释放表

#14


加上事务隔离*别:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
加在begin tran 之前

表示:
1.  语句不能读取已由其他事务修改但尚未提交的数据。 
2.  任何其他事务都不能在当前事务完成之前修改由当前事务读取的数据。 
3.  在当前事务完成之前,其他事务不能使用当前事务中任何语句读取的键值插入新行。 

#15


还是没解决,先结贴吧,谢谢各位了

#16


在begin try之后,begin tran之前,加一句: set transaction isolation level serializable

#1


这个代码是不是你写的?
应该去了解为什么要这样控制数据,是不是因为业务逻辑的需要?只要它数据正确,运行符合业务逻辑要求,更新多次不是不可以。

#2


@hdhai9451  是我写的,业务是这样需求,这种状况也不是经常出现,偶尔会出现这种状况吗 
数据库并发是不是会出现这种问题

#3


那你就必须使用事务处理
betin tran
..............
....
commit tran

rollback tran

有关事务你应该了解吧,事务具有原子性、隔离性、持久性、一致性
执行代码要么全部成功,要么全部失败,使用事务再多的并发也不怕 错误


#4


求大神指点,sqlserver 数据库并发,造成数据多次更改
事务是有用上,具体没深入了解,不像是事务过程多次执行,到有点像用户余额被更新了

#5


是否执行多次,你写入日志文件不就知道了吗?
你在update语句后面加入写日志 insert into tblog(dt) values(getdate())

我认为不会执行多次的

#6


引用 4 楼 zgl_11 的回复:
求大神指点,sqlserver 数据库并发,造成数据多次更改
事务是有用上,具体没深入了解,不像是事务过程多次执行,到有点像用户余额被更新了

userinfo是记录余额的表吗?
你怎么知道执行了多次?AccountDetails中记录了相同的记录多次吗?

#7


更新不会多,只会是插入少了

这种情况,必须自己加串行化,否则更糟的事情都会发生。。。

#8


@szm341
userinfo有个保存余额的字段
 是啊,多出的金额,是之前更新的数据

#9


@hdhai9451
没有执行多次,明细只有一条,余额间断性的多出同个数据

#10


@sz_haitao
自己加入串行化是什么意思

#11


在程序无bug的前提下,有两种办法
1.提高事务的隔离级别,会降低性能
2.放弃绝对一致性,采用最终一致性;利用对账程序来对齐余额

#12


引用 8 楼 zgl_11 的回复:
@szm341
userinfo有个保存余额的字段
 是啊,多出的金额,是之前更新的数据

@在这里是没用的,需要点“引用”
其实我主要想问AccountDetails中记录了相同的记录多次吗? 
因为你的存储过程是事务模式,那么只有同时添加了记录并且成功,才会多执行一次update
如果没有这个多出来的记录,那肯定是你在执行存储过程其他的地方有操作,或者是有触发器一类比较隐蔽的操作在执行,当然也有可能有什么作业,总之肯定不会是你截图的存储过程的问题

#13


更新之前先锁表,更新后再释放表

#14


加上事务隔离*别:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
加在begin tran 之前

表示:
1.  语句不能读取已由其他事务修改但尚未提交的数据。 
2.  任何其他事务都不能在当前事务完成之前修改由当前事务读取的数据。 
3.  在当前事务完成之前,其他事务不能使用当前事务中任何语句读取的键值插入新行。 

#15


还是没解决,先结贴吧,谢谢各位了

#16


在begin try之后,begin tran之前,加一句: set transaction isolation level serializable