高手帮小弟分析一个带事务的存储过程?
CREATE PROCEDURE p_set_time_send
AS
begin
SET XACT_ABORT ON
begin tran zhuanyidingshifasong
insert into tb_queue_list select * from tb_set_time_msg where send_time <= getdate()
delete from tb_set_time_msg where send_time <= getdate()
commit tran zhuanyidingshifasong
end
go
请大家帮我分析一下我写的这个带事务的存储过程有没有问题.
这个存储过程的功能:从一个表中把满足一定时间的数据,写到另一个表中.并把刚才满足条件的数据清空.
现在小弟有一点不明,请指点.就是通过insert into tb_queue_list select * from tb_set_time_msg where send_time <= getdate()写入的数据,会不会通过delete from tb_set_time_msg where send_time <= getdate()删除的数据不一样多.
会不会出现:在删除前又有满足条件的数据写入 tb_set_time_msg ,但这些数据没有被写入tb_queue_list. 说明 tb_queue_list,tb_set_time_msg结构一样.
------解决方案--------------------依照这样的写法,理论上讲是会出现你所担心的问题的
就是插入tb_queue_list表的数据可能和你接下来做删除的数据存在出入
建议你将要插入的数据存放到一个只读的临时表,然后依据临时表的内容再做删除,当然也可以使用游标。
我这里说一下游标的方案:
1:将需要删除的数据保存到游标里,select * from tb_set_time_msg where send_time <= getdate() ,游标要这样声明DECLARE YOURCURSOR CURSOR LOCAL STATIC FOR,关键字STATIC可以保证你的游标数据不会因为数据库表里数据的增删而有所改变。
2:在游标循环里,将数据逐一执行tb_queue_list表的插入和tb_set_time_msg表的削除。
------解决方案--------------------在删除前又有满足条件的数据写入 tb_set_time_msg ,但这些数据没有被写入tb_queue_list.
事务中的插入操作和删除操作只要条件一样就不会出现楼主担心的问题。
要保持条件一样,关键在使得两次的限制时间一样。
将插入时getdate的值保存在一个参数中,把这个参数作为删除时的时间条件就行了