|
紧急求救:Transaction Locking- Track table要是一直update delete会怎样?
[复制链接]
|
|
发表于 15-12-2006 01:28 AM
|
显示全部楼层
Transaction begin
Update Table A [Status]
Select Table A [Status] Where A.BID = aaa
根据以上的select到的结果:
Update Table B [Status] where B.BID = aaa
Select Table B [Status] where B.CID = bbb
根据以上的select到的结果:
Update Table C [Status] where C.CID = bbb
Update Table C [StatusOrg] where C.CID = bbb
Transaction Commit
了解到以上的过程几乎是一气呵成的... 我想...方法有两个:
1. 我上面提到, check in/check out 你的 record, 还没 commit 没人可以尝试去 update.
2. 修改你的程序.
a. 当你 Update Table A 完毕后, 基本上是不是可以立即 commit 了?
b. 这样当你在 Update Table B 的时候, 有别人进来 Update Table A, 你是希望他看到旧的资料呢, 还是最新的资料? 如果是最新的资料... 基本上你可以立即 commit, 相信你的问题也可以解决.
c. 如果照 a 和 b 来做, 那么在 Update Table C 的时候... 失败了怎么办? 这时候, 一般地说, 会有 error log 来记录着, 这样发生错误的话, 就可以采取措施. 我在某些任务上就是那样来做. |
|
|
|
|
|
|
|
楼主 |
发表于 15-12-2006 09:36 AM
|
显示全部楼层
原帖由 goatstudio 于 15-12-2006 01:28 AM 发表
1. 我上面提到, check in/check out 你的 record, 还没 commit 没人可以尝试去 update.
2. 修改你的程序.
a. 当你 Update Table A 完毕后, 基本上是不是可以立即 commit 了?
b. 这样当你在 Update Table B 的时候, 有别人进来 Update Table A, 你是希望他看到旧的资料呢, 还是最新的资料? 如果是最新的资料... 基本上你可以立即 commit, 相信你的问题也可以解决.
c. 如果照 a 和 b 来做, 那么在 Update Table C 的时候... 失败了怎么办? 这时候, 一般地说, 会有 error log 来记录着, 这样发生错误的话, 就可以采取措施. 我在某些任务上就是那样来做.
对~就是这个一气呵成让我很头痛~
1.所谓的check in check out,是不是自己去放一个flag,然后告诉user 这个纪录不能用?基本上我们讨论了,觉得user很可能不太会要接受,因为这样子visible to them,很多人一齐用的时候,大家都会要等来等去。我是比较希望能够做到Invisible to them..
2.这是一气呵成的一个flow, 任何一环失败了,一定要从头到尾都rollback..要是之后才补救,就来不及的了。因为a,b,c = 一个 A process...A process 又会影响下一个 B Process...一个失败了的process会造成一串骨牌效应。
说白一点,我这个是一个品质管理的系统。在运输带上,第一个产品坏了,影响第二个产品的级别,然后第三个,第四个。 所以,整个process互相牵连,transaction没办法拆开。
暂时,我现在是在做identifying problem.
第一个发现是Update crash,真个没办法的话很可能就会用方法一。
第二个发现是两个同时insert, 也有问题。请问,这个是为什么呢? |
|
|
|
|
|
|
|
发表于 15-12-2006 10:48 AM
|
显示全部楼层
回复 #20 雨吟 的帖子
如果没有 primary key 或 index , 如果我没弄錯的话. MS SQL 2000会用table level lock.
猜测你的 transaction setting 是 report error immediate when locking.
不是waiting for lock until timeout.
如果是 report error immediate when locking
你可以用以下方法. (我是在MS TechEd 2006 看到的demo).
用 try and catch control.
在 catch里 如果 lock found 就 re-try update 或 问 user 要不要 re-try update. |
|
|
|
|
|
|
|
发表于 15-12-2006 11:03 AM
|
显示全部楼层
回复 #15 雨吟 的帖子
我用以下的script simulate. Result ok.
User B 只是在 waiting 而且.没有 error.
create table temp1 (col1 int not null, col2 int);
alter table temp1 add constraint pk_temp1 primary key (col1);
create table temp2 (col1 int not null, col2 int);
alter table temp2 add constraint pk_temp2 primary key (col1);
create table temp3 (col1 int not null, col2 int);
alter table temp3 add constraint pk_temp3 primary key (col1);
insert into temp1(col1, col2) values (1,1);
insert into temp1(col1, col2) values (2,1);
insert into temp2(col1, col2) values (1,1);
insert into temp2(col1, col2) values (2,1);
insert into temp3(col1, col2) values (1,1);
insert into temp3(col1, col2) values (2,1);
------------------------------
--User A and B simulation
--using two Query Analyzer sessions
------------------------------
begin transaction
select * from temp1 where col1 =2;
update temp1 set col2=1 where col1=2;
select * from temp2 where col1 =1;
update temp2 set col2=1 where col1=1;
select * from temp3 where col1 =1;
update temp3 set col2=1 where col1=1;
commit; |
|
|
|
|
|
|
|
楼主 |
发表于 15-12-2006 11:06 AM
|
显示全部楼层
原帖由 悠哉亭 于 15-12-2006 10:48 AM 发表
如果没有 primary key 或 index , 如果我没弄錯的话. MS SQL 2000会用table level lock.
猜测你的 transaction setting 是 report error immediate when locking.
不是waiting for lock until timeout.
...
怎么样去看transaction setting?
在query analyzer 跑,的确是没问题。。。在application 跑,才遇到问题~
[ 本帖最后由 雨吟 于 15-12-2006 11:08 AM 编辑 ] |
|
|
|
|
|
|
|
发表于 15-12-2006 12:21 PM
|
显示全部楼层
顺便告诉你我之前遇到的问题。。我用mysql,有5架server 做SYNC,如果其中一个TABLE LOCKING或ROW LOCKING,这也会导致SYNC 断的,所以就要KILL PROCESS。。^^ |
|
|
|
|
|
|
|
发表于 15-12-2006 12:35 PM
|
显示全部楼层
|
|
|
|
|
|
|
楼主 |
发表于 15-12-2006 02:21 PM
|
显示全部楼层
原帖由 max5007 于 15-12-2006 12:21 PM 发表
顺便告诉你我之前遇到的问题。。我用mysql,有5架server 做SYNC,如果其中一个TABLE LOCKING或ROW LOCKING,这也会导致SYNC 断的,所以就要KILL PROCESS。。^^
你的user 接受你这样子Kill process 吗?
我们这里也是Kill了就好了。。。
但是,不可能我们请一个人坐在那里专门Kill process吧?user 那里会杀掉我们 |
|
|
|
|
|
|
|
楼主 |
发表于 15-12-2006 03:19 PM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 15-12-2006 06:05 PM
|
显示全部楼层
原帖由 雨吟 于 15-12-2006 02:21 PM 发表
你的user 接受你这样子Kill process 吗?
我们这里也是Kill了就好了。。。
但是,不可能我们请一个人坐在那里专门Kill process吧?user 那里会杀掉我们
我们有写一个tools来monitor这个东西的。。如果lock table or row,就会把那process杀掉,然后把syncronize接回去,不过最好的方法还是检查coding那里 |
|
|
|
|
|
|
|
发表于 16-12-2006 02:39 AM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 17-12-2006 04:28 PM
|
显示全部楼层
原帖由 雨吟 于 15-12-2006 03:19 PM 发表
..
现在只是剩下update crash...造成的row level locking...比较可能是notify user record lock,这是挺逻辑的事,应该不难说服他们接受~
可以分享一下,你们做过的解决方法吗
...
到目前为止, 我都是用row level locking 的方法来控制及产生 invoice #等等.
QA team, test 过多用户一致执行的simulation.都没问题.
可惜coding 不是我负责.
有时间的话, 你可以看看你们的data model design, 看有何地方可以改善. |
|
|
|
|
|
|
|
楼主 |
发表于 19-12-2006 04:19 PM
|
显示全部楼层
谢谢各位的帮忙~
我只要让两个同时被call 的Transaction 慢1秒钟跑,就完全不会有问题的了。
所以,我在global 那里做了一个memory的datatable, 记录是否有同一个record的Transaction在跑,Track 到有的那个user, 用coding帮他按多一次button,让同时间的action变成差一点点。。。耶耶~
这样子,我会不会忽略了什么呢?so far 是可以work...然而,我会更感激你们的意见,毕竟我还是新菜鸟
[ 本帖最后由 雨吟 于 19-12-2006 04:21 PM 编辑 ] |
|
|
|
|
|
|
|
楼主 |
发表于 20-12-2006 11:31 AM
|
显示全部楼层
刚刚想到一个问题,似乎无可避免要用到physical table 来keep track row level lock 了。。。
因为我们有Job,job 可能会Interfere 到application正在Update的record...Job read 布到application 里的datatable....
问题是,这样子的一个database table, 每几秒都一直在insert, delete, insert, delete,会不会有什么Impact?
[ 本帖最后由 雨吟 于 20-12-2006 11:33 AM 编辑 ] |
|
|
|
|
|
|
| |
本周最热论坛帖子
|