插入数据的时候,如何避免与之相关的表数据被更改?
表结构如下,在px和spec表中已经存在相关数据情况下,要插入数据到goods表中
如果要插入的数据非常多,那要如何避免此时用户对相应px和spec表中的数据进行修改呢?
假设插入的是10万条 pid=1,sid随机的数据,10万条数据要插入也得一段时间
如果此时有别的用户打开px.id=1的数据,并进行插入数据的话,那该如何限制让B的提交无效呢?
如果是A和B用户都打开px.id=1的数据,A用户先提交插入10万条数据,而在A提交后,B也提交,那又该如何限制让B无法插入呢?
INSERT INTO `goods`(`pid`,`sid`) VALUES
(1,1),(1,2),(1,2),(1,3),(1,3),(1,3);
-
SQL code
/* 建表语句 */ DROP DATABASE IF EXISTS `testtest`; CREATE DATABASE `testtest` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; USE `testtest`; DROP TABLE IF EXISTS `px`; CREATE TABLE IF NOT EXISTS `px` ( `id` int(2) NOT NULL AUTO_INCREMENT, `desc` varchar(10) CHARACTER SET gbk DEFAULT NULL, `isdel` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除(0:不删除|1:删除)', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; DROP TABLE IF EXISTS `spec`; CREATE TABLE IF NOT EXISTS `spec` ( `id` int(2) NOT NULL AUTO_INCREMENT, `pid` int(2) NOT NULL, `isdel` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除(0:不删除|1:删除)', PRIMARY KEY (`id`), KEY `pact_id` (`pid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; DROP TABLE IF EXISTS `goods`; CREATE TABLE IF NOT EXISTS `goods` ( `id` int(4) NOT NULL AUTO_INCREMENT, `pid` int(2) NOT NULL, `sid` int(2) NOT NULL, `isdel` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除(0:不删除|1:删除)', PRIMARY KEY (`id`), KEY `pid` (`pid`), KEY `sid` (`sid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; /* 添加约束 */ ALTER TABLE `goods` ADD CONSTRAINT `goods_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `px` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `goods_ibfk_2` FOREIGN KEY (`sid`) REFERENCES `spec` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `spec` ADD CONSTRAINT `spec_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `px` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; COMMIT; /* 插入数据 */ INSERT INTO `px`(`isdel`) VALUES (0),(0),(0); INSERT INTO `spec`(`pid`) VALUES (1),(1),(1),(2),(2),(3),(3); /* 添加触发器 */ /* 更新px的isdel字段时,更新spec和goods的isdel字段 */ DELIMITER $$ CREATE TRIGGER `hidden_px` BEFORE UPDATE ON `px` FOR EACH ROW BEGIN UPDATE `spec`,`goods` SET `spec`.`isdel` = NEW.`isdel`,`goods`.`isdel` = NEW.`isdel` WHERE NEW.`id` = `spec`.`pid` AND NEW.`id` = `goods`.`pid`; END$$ DELIMITER ; COMMIT;
LOCK TABLES
但是goods表进行insert操作的时候,别的用户也经常对这3个表进行SELECT和UPDATE操作哦…
这样不就会导致其他用户的操作变慢了??
那没办法。加锁和冲突是难免的。程序设计者需要在两者间平衡。
BTW,锁行的关键字是什么??
由MYSQL自行决定。
可以参考文档中的锁相关介绍。
MySQL官方文档 http://dev.mysql.com/doc/refman/5.1/zh/index.html
即是说连LOCK TABLES都不必,InnoDB数据库引擎会自动进行锁行??
建议看一下手册中在哪些情况下会锁表。 比如事务中。 那么事务是否开启了?。。。。