mysql事务处理
在说事务之前要先确定你的数据表的存储类型。因为myisam不支持事务,支持全文索引;而myinnodb支持事务,但不支持全文索引。
MyISAM 是MySQL中默认的存储引擎,一般来说不是有太多人关心这个东西。决定使用什么样的存储引擎是一个很tricky的事情,但是还是值我们去研究一下,这里的文章只考虑 MyISAM 和InnoDB这两个,因为这两个是最常见的。
下面先让我们回答一些问题:
◆你的数据库有外键吗?
◆你需要事务支持吗?
◆你需要全文索引吗?
◆你经常使用什么样的查询模式?
◆你的数据有多大?
myisam只有索引缓存
innodb不分索引文件数据文件 innodb buffer
myisam只能管理索引,在索引数据大于分配的资源时,会由操作系统来cache;数据文件依赖于操作系统的cache。innodb不管是索引还是数据,都是自己来管理
思考上面这些问题可以让你找到合适的方向,但那并不是绝对的。如果你需要事务处理或是外键,那么InnoDB 可能是比较好的方式。如果你需要全文索引,那么通常来说 MyISAM是好的选择,因为这是系统内建的,然而,我们其实并不会经常地去测试两百万行记录。所以,就算是慢一点,我们可以通过使用Sphinx从 InnoDB中获得全文索引。
数据的大小,是一个影响你选择什么样存储引擎的重要因素,大尺寸的数据集趋向于选择InnoDB方式,因为其支持事务处理和故障恢复。数据库的在小决定了 故障恢复的时间长短,InnoDB可以利用事务日志进行数据恢复,这会比较快。而MyISAM可能会需要几个小时甚至几天来干这些事,InnoDB只需要 几分钟。
您操作数据库表的习惯可能也会是一个对性能影响很大的因素。比如: COUNT() 在 MyISAM 表中会非常快,而在InnoDB 表下可能会很痛苦。而主键查询则在InnoDB下会相当相当的快,但需要小心的是如果我们的主键太长了也会导致性能问题。大批的inserts 语句在 MyISAM下会快一些,但是updates 在InnoDB 下会更快一些——尤其在并发量大的时候。
所以,到底你使用哪一个呢?根据经验来看,如果是一些小型的应用或项目,那么MyISAM 也许会更适合。当然,在大型的环境下使用 MyISAM 也会有很大成功的时候,但却不总是这样的。如果你正在计划使用一个超大数据量的项目,而且需要事务处理或外键支持,那么你真的应该直接使用 InnoDB方式。但需要记住InnoDB 的表需要更多的内存和存储,转换100GB 的MyISAM 表到InnoDB 表可能会让你有非常坏的体验。
在这片文章的例子中,我们使用 "employee","telephone"表。
创建 employee表:
CREATE TABLE `employee` ( `id` int NOT NULL AUTO_INCREMENT, `first_name` varchar(100) NOT NULL, `last_name` varchar(100) NOT NULL, `job_title` varchar(100) DEFAULT NULL, `salary` double DEFAULT NULL, `notes` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建 telephone表:
CREATE TABLE `telephone` ( `id` int NOT NULL AUTO_INCREMENT, `employee_id` int DEFAULT NULL, `type` varchar(20) NOT NULL, `no` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
设想你需要一个新的叫做Grace Williams雇员,并带有他的电话号码信息。你可能会执行下面两句sql:
INSERT INTO `employee` (`id`, `first_name`, `last_name`, `job_title`, `salary`) VALUES (NUll, 'Grace', 'Williams', 'Softwaree Engineer', 5000);
INSERT INTO `telephone` (`id`, `employee_id`, `type`, `no`) VALUES (NULL, 1, 'mobile', '270-598712');
mysql处理事务由三种方式:
1、用begin,rollback,commit来实现
begin 开始一个事务
rollback 事务回滚
commit 事务确认
<?php
header("Content-Type:text/html;charset=utf-8");
//$salary = 5000;
$salary = '$5000';
/* Change database details according to your database */
mysql_connect('localhost', 'root', '');
mysql_select_db('transaction');
$employeeid = "";
//开始一个事务
mysql_query("BEGIN"); //或者mysql_query("START TRANSACTION");
$query1 = "INSERT INTO `employee` (`id`, `first_name`, `last_name`, `job_title`, `salary`) VALUES (NULL, 'Grace', 'Williams', 'Softwaree Engineer', '$salary')";
$query2 = "INSERT INTO `telephone` (`id`, `employee_id`, `type`, `no`) VALUES (NULL, $employeeid, 'mobile', '270-598712')";//错误语句,需要回滚
$res = mysql_query($query1);
$employeeid = mysql_insert_id();
$res1 = mysql_query($query2);
if($res && $res1){
mysql_query("COMMIT");
echo '提交成功。';
}else{
mysql_query("ROLLBACK");
echo '数据回滚。';
}
mysql_query("END");
mysql_query("SET AUTOCOMMIT=1");
$query3 = "INSERT INTO `employee` (`id`, `first_name`, `last_name`, `job_title`, `salary`) VALUES (NULL, 'emmy', 'my', 'Softwaree Engineer', '$salary')";
$res = mysql_query($query3);
?>
2、直接用set来改变mysql的自动提交模式
MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过
set autocommit=0 禁止自动提交
set autocommit=1 开启自动提交
来实现事务的处理。
<?php
header("Content-Type:text/html;charset=utf-8");
//$salary = 5000;
$salary = '$5000';
/* Change database details according to your database */
mysql_connect('localhost', 'root', '');
mysql_select_db('transaction');
$employeeid ="";
mysql_query("SET AUTOCOMMIT=0"); //设置mysql不自动提交,需自行用commit语句提交
$query1 = "INSERT INTO `employee` (`id`, `first_name`, `last_name`, `job_title`, `salary`) VALUES (NULL, 'Grace', 'Williams', 'Softwaree Engineer', '$salary')";
$query2 = "INSERT INTO `telephone` (`id`, `employee_id`, `type`, `noS`) VALUES (NULL, $employeeid, 'mobile', '270-598712')";//错误语句,需要回滚
$res = mysql_query($query1);
$employeeid = mysql_insert_id();
$res1 = mysql_query($query2);
if($res && $res1){
mysql_query("COMMIT");
echo '提交成功。';
}else{
mysql_query("ROLLBACK");
echo '数据回滚。';
}
mysql_query("SET AUTOCOMMIT=1");
$query3 = "INSERT INTO `employee` (`id`, `first_name`, `last_name`, `job_title`, `salary`) VALUES (NULL, 'emmy', 'my', 'Softwaree Engineer', '$salary')";
$res = mysql_query($query3);
?>
3、锁定表法
<?php
mysql_query("LOCK TABLES `employee` WRITE");//锁住`user`表
$sql = "INSERT INTO `employee` (`id`, `first_name`, `last_name`, `job_title`, `salary`) VALUES (NULL, 'emmy', 'my', 'Softwaree Engineer', '$salary')";
$res = mysql_query($sql);
if($res){
echo '提交成功。!';
}else{
echo '失败!';
}
mysql_query("UNLOCK TABLES");//解除锁定
?>
by simpman
浙公网安备 33010602011771号