socket通信控制,超难问题,各路高人请进入探讨对策。(50分)

  • 主题发起人 主题发起人 sjg23690428
  • 开始时间 开始时间
S

sjg23690428

Unregistered / Unconfirmed
GUEST, unregistred user!
要求:socket客户端向socket服务端发送一条SQL语句,并通过服务端程序向数据库中执行。
我本人提出解决方案,共大家探讨。
1.客户端向服务端发送自定义格式字符串,例如 00300005update aaa set bbb='c'
0030 发送字符总长度,0005 执行SQL语句最长时间, update aaa set bbb='c' 为实际要执行的SQL语句。
2.客户端等待服务端执行结果,等待最长时间为0005+2, 服务端接收到信息后,解析出要执行SQL语句最长时间“0005”与SQL语句“update aaa set bbb='c'”,数据库中已经写好了执行SQL语句的存储过程,存储过程有三个参数,分别为(执行最长时间、SQL语句、执行状态)。存储过程主要功能为,执行客户端传来的SQL语句。
3.如执行SQL语句错误则通过“执行状态”变量返出“执行错误”信息,并发送到客户端。 客户端根据此返回信息做出相应处理,
4.如SQL语句执行的时间大于0005秒,则存储过程回滚刚执行的SQL语句。并不向客户端发送认何信息。这时客户端,等待返回信息的时间必定会到0005+2秒,客户端就认为传送数据超时。 这样主要是为解决SQL语句执行时间大于了客户端的等待时间。
5.如SQL语句执行正确并在设定时间内执行完成,则向客户端返回执行成功信息。
6.当客户端收到“执行成功”信息后,则客户端删除已发送的信息。
7.客户端如收到,“执行错误”,则会发送下一条SQL语句,而错误SQL语句则等待人工处理。
8.客户端发送数据超时,则会重新发送此条SQL语句。

以上是我现在所用的socket传送机制,不知道我说的大家能否看明白。以上处理机制有几个问题,但我还不知道怎么解决。但出错的几率不高。

第1问题,如SQL语句在设定时间内正确执行。并在返回客户端“成功执行”信息时,出现网络问题,此时客户端就无法收到“成功执行”信息,就会认为发送超时,但此时服务端其实已经成功执行了SQL语,当网络正常后,客户端会重新发送此SQL语句。
如果发送的SQL语句是"insert"插入语句,此时就会出现,发送数据重复的现象。
哈哈.....各位高人,看看谁有高招
[:)][:)][:)][:)][8D][8D][8D]
 
这个问题确实不好整! 我的做法是本地记录一下上次提交的单据, 返回正确则删除他! 如果错误或者超时就就是使用本地的单据去查询服务, 如果存在服务的话, 就删除他。 保证数据的一至性。
 
我觉得你需要把数据库与socket通信分开当成两件事来做。
sql语句成功或失败,均告诉客户端。
====
第1问题,如SQL语句在设定时间内正确执行。并在返回客户端“成功执行”信息时,出现网络问题,此时客户端就无法收到“成功执行”信息,就会认为发送超时,但此时服务端其实
===
你说的问题其实是在回传执行结果的当口,服务器上已经成功了,而在告诉客户端执行结果时失败了,因为服务器成功了,只是回传结果失败,那么对于数据库服务器来说是无法知道的。在数据库级别上控制就可以了,比如你可以对某个字段设成唯一属性,使下次提交不成功等。

感觉是个牛角尖的问题 :)
 
楼上的这个不是牛角尖的问题。 客户得不到返回信息! 就不知道失败还是成功。 如果是关于到钱的交易估计很难说得清楚!
 
大家,对这难度问题都不敢兴趣吗?
 
服务器执行成功,传输过程失败,你除了再次验证,还有什么高招。
socket只是传输层的事,你跟数据库绑在一起搞,找不出什么好办法的。

我年前碰到的事:
取款机取钱,机器数完钱了,但钱没吐出来,刚好atm机进入维护状态了,通过手工查帐,发现我的钱已经被扣了,但是我没拿到钱,唯一解决的方法就是把取款机的钱取出来人工数,确定我没拿到这个钱。
也就是说只有通过再次验证。不过一般写程序时不用去考虑这些事的。
这个就是个控制的粒度问题。
并且上面说的用超时什么,不是解决的方法。
 
可以试试,定义一个唯一的发送序列号,若这个序列号已经存在,则返回已经执行的错误,建议用存储过程,客户端直接INSERT的很少用的, 当未知情况发生时,再次发送时 insert失败就行了
 
我做过, 把数据从山东威海传到北京. 并可以在山东查询,更新, 删除 北京的数据.
所有的数据都是通过socket 传输的.
 
用TCP就行了,加个ID号
 
可以用这个方式看看

insert into ( xxx ) values (xxx ) where id not in (select id from xxx )
 
这问题,你在协议上,再增加一个确认处理就好了

Client
Server

Request_1 // client->server 如上面你的"00300005update...."
Response_1 // server->client 表明server接受此请求,如"OK"
Request_2 // server->client 通知client,某个请求我完成,并返回结果,如"0030OK"
Response_2 // client->server,收到

这样就好,你的协议处理的命令比较少,增加几条确认就好了,这个,写协议好像都是这样的吧。
request和response一般都是成对出现,response未收到,则进行周期性的request
 
每条命令加个SessionID。
 
这问题,你在协议上,再增加一个确认处理就好了

Client
Server

Request_1 // client->server 如上面你的"00300005update...."
Response_1 // server->client 表明server接受此请求,如"OK"
Request_2 // server->client 通知client,某个请求我完成,并返回结果,如"0030OK"
Response_2 // client->server,收到

这样就好,你的协议处理的命令比较少,增加几条确认就好了,这个,写协议好像都是这样的吧。
request和response一般都是成对出现,response未收到,则进行周期性的request

你能不能在说的清楚点啊。
 
后退
顶部