<?phpinclude("config.inc.php");
$db=new db();
echo date('h:i:s') . "<br />";$db->execute("begin");$rs=$db->getRs("select * from book where sum>0 and id =1");
sleep(5);
if($rs->rowCount())//如果存在可借的书籍
$db->execute("update book set sum=sum-1 where id =1");$db->execute("commit");echo date('h:i:s');?>
数据库为
CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sum` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbkinsert into book(sum) values(1); 我在火狐里运行一下,然后2秒后在ie里运行,最后book表的sum字段为-1了,直接在程序前后加上begin和commit并没有实现事务的功能,我试过在select 语句后加上for update ,执行后sum最后为0(符合我的 目的,)那我想问,对于复杂的事务,除了for update还有别的方法么
SET autocommit=0; 后再试一下
改成$db->execute("set autocommit=0");
$db->execute("begin");也没用,sum还是-1
innodb事务和其他数据库如SQL SERVER有点不一样。
开启事务后, select语句并不会自动锁行(serializable隔离除外,但是加share锁),必须手工加share或exclusive锁。
你的问题,必须加exclusive锁, 加share锁是没有用处,所以只能用for update
select for update 是加的拍它鎖吧,另外
還有一個問題,select * from book where sum>0 and id =1 for upadte
如果字段id沒有索引,將會把整個book表加鎖
還有一個問題,select * from book where sum>0 and id =1 for upadte
如果字段id沒有索引,將會把整個book表加鎖
for update
对 for update ,lock in share mode,update,delete 起冲突,但对一般的select不冲突lock in share mode
对 for update,update,delete 起冲突, 但对lock in share mode,一般的select不冲突