由于拉的太长了,所以开了个新帖,顺便提一点关于小型支付系统中因为不了解MYSQL所以出现的疑惑

(发这帖子之后,自己又做了个模拟的试验,建立一个INNODB表,存储一条记录,同时建立一个存储过程,只是UPDATE这个表)

CREATE DEFINER=`root`@`localhost` PROCEDURE `test`(out p_sErrorMsg char(50))
BEGIN
DECLARE m_iCount INT DEFAULT 0;
DECLARE m_iCredit INT DEFAULT 0;
DECLARE m_iLoansum INT DEFAULT 0;
DECLARE m_sTempStr char(30) default '';
DECLARE m_sTempId char(30) default '';
DECLARE EXIT HANDLER FOR NOT FOUND BEGIN ROLLBACK; SET p_sErrorMsg = 'NOT FOUND'; END;
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SET p_sErrorMsg = 'SQLEXCEPTION'; END;
DECLARE EXIT HANDLER FOR SQLWARNING BEGIN ROLLBACK; SET p_sErrorMsg = 'SQLWARNING'; END;
START TRANSACTION;
update account set sum_gold=sum_gold-100 where sum_gold>=100;

END

然后开两个命令行客户端连接,分别设置autocommit=0.当第一个执行CALL TEST();后,先不执行COMMIT,而是到第二个连接中去执行CALL TEST();,发现第二个貌似是被阻塞住了。第一个执行完COMMIT,第二个才执行,由于在UPDATE中加入了条件限制,并未出现负数。应当是阻塞在了UPDATE这句话上,INNODB是行锁。。。是否在程序中也会如此。。。就不大清楚了

——————————————————————————————————————————————————————
原文

老兄你把前面我贴上的DUMP出来的内容倒入test1库就可以了,然后在account表里随便加入自己一个帐号吧, 其中的user_id给1就可以了,因为我在ad_publish_old中是直接CALL spanmoney(1,1,5,@sErrorMsg);,把参数些定了。
ad_publish_old中就是我给你描述的那种问题,只要CALL spanmoney(1,1,5,@sErrorMsg);,那么前面所有的INSERT 及 UPDATE就会被隐性的COMMIT,所以,我在ad_publish中,只能把CALL spanmoney(1,1,5,@sErrorMsg);放在最前面执行。老兄多费心了

另外,当老兄看完上面那个问题后有个相关联的问题,我还想请教下老兄。问题是这样的,如果按照我平常的思路,一个支付系统在完成一个订单,也就是产生一定货币流动的时候所要进行的处理最好都要放入一个事务处理中,但是由于对MYSQL对存储过程的处理机制不是很了解,所以一直有些疑惑。比如当用户进行某种交易后,我要把一用户的一些数据改变,改变后将用户帐户中的货币数量进行改变(比如减少货币的操作),当然我在改变用户帐户里的货币的时候,存储过程中肯定要进行判断的。但是,问题是否也就会出现在这里。如果用户同时下10个订单,那么当一号订单的存储过程进行用户帐户中的货币数量改变的时候,二号订单的存储过程是否会并发进行,如果是的话,那么就很可能当一号订单没有做COMMIT的时候,二号订单就开始对用户帐户内的剩余金额进行判断,而由于订单都不是在同一个进程内完成的,所以一号订单没有COMMIT前,二号订单的存储过程所判断的数据是在一号订单减少货币前的数据,这样就有可能误认为用户剩余金额够完成订单而进行减少货币的操作进而完成整个订单。。。其实这个问题换个问法就是存储过程是否会在服务器端序列化。。。如果不序列化的话就只能通过再添加一张表(INNODB)进行锁的操作来限制一个用户一个时间点只能完成一个订单。因为对MYSQL整个的机理还不是很了解,所以就得麻烦老兄了

Taxonomy upgrade extras:

内容太多,又乱,看的头大.先贴上2个存储过程吧.
阅读下手册的"13.5.10.1. InnoDB Lock Modes"这节,尤其是"13.5.10.6. Next-Key Locking: Avoiding the Phantom Problem"部分

MySQL方案、培训、支持
MySQL 用户组

看了,已了解,谢谢老兄呀,看来是俺看书不仔细