PHP mysql的重复打开事务问题,高手进~~~~ 本帖最后由 xanewong111 于 2011-03-23 17:42:44 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 function begin_transaction($cnn) { static $flag; if(isset($flag)) return ; mysql_query("BEGIN", $cnn); //这里可以有一些错误处理机制 $flag = 1;} 另外还有两种方案1. 使用mysqli的事务支持...(需要使用mysqli扩展)$mysqli = new Mysqli($host, $username, $password, $db);$mysqli->autocommit(false);//其他处理2. 框架处理方式(借鉴java开源框架spring的事务处理)如果请求的处理有统一的入口, 那么在入口处开启事务, 并在对具体业务调用的包装处, 根据异常或错误机制, 进行事务的回滚, 提交的管理. 方法很多, 除了楼上的, 在这里我附加一个, 没测试,function a(){ mysql_query("BEGIN"); //开始事务定义 mysql_query("insert into table1 ....."); mysql_query("COMMIT"); //执行事务 define('A',true);}function b(){ mysql_query("BEGIN"); //开始事务定义 mysql_query("update table2 ....."); mysql_query("COMMIT"); //执行事务 define('B',true);}function c(){ mysql_query("BEGIN"); //开始事务定义 mysql_query("delete table3 ....."); //调用a和b方法 if( !defined('A')) a(); if( !defined('B')) b(); mysql_query("COMMIT"); //执行事务}c(); 你的意思是将begin封装一下,在开始之前进行一个检测?我不知道你的这个代码是否能起到检测的效果。明天我测试一下 第一个方法我没看懂,这个和自动提交有关系吗?PS:我不能要求服务器必须有mysqli扩展,暂时否掉第二个方法就是最终解决方案,我不知道如何实现spring里的这个东西,类似AOP的东西,求解啊。 按道理mysql这个重复begin应该返回一个错误或警告,但是似乎没有。除了1/2楼的方法, 你可以用 set autocommit=0 来开始事务,用 commit; set autocommit=1; 或 rollback; set autocommit=1; 来结束/回滚一个事务这样在a()和b()里可以用 select @@autocommit; 来看是否在事务中间,注意不仅是开始事务的begin前需要判断,更重要的是commit前需要判断,因为重复begin不回出错,提前commit才是出错的直接原因 这个不太对啊好像。实际上,执行的c方法,代码就就变成了:function c(){ mysql_query("BEGIN"); //开始事务定义 mysql_query("delete table3 ....."); //下边的2个事务实际上是a和b方法里面的 mysql_query("BEGIN"); //开始事务定义 mysql_query("insert into table1 ....."); mysql_query("COMMIT"); //执行事务 mysql_query("BEGIN"); //开始事务定义 mysql_query("update table2 ....."); mysql_query("COMMIT"); //执行事务 mysql_query("COMMIT"); //执行事务}现在问题就出来了,里面有3组事务,我的意思是想中间的2组事务,有个监测功能,监测如果上边已经打开了事务,那么就不重复打开了,否则各个事务都生效,那就乱套了,并且失去了事务的意义了。 补充:我的意思是想中间的2组事务,有个监测功能,监测如果上边已经打开了事务,那么就不重复打开并且重复commit了。只有第一个begin和最后一个commit生效 mysqli的方案和7楼说的是一个意思, 是设置了数据库的autocommit=false. 最终commit/rollbackfunction begin_transaction($cnn) { static $flag; if(isset($flag)) return ; mysql_query("BEGIN", $cnn); //这里可以有一些错误处理机制 $flag = 1;}1楼我写的这个方法是使用了函数的静态变量来做标记, 对开启事务做一个封装, 这个你可以测试, 是没有问题的...另外, 如果你用面向对象的方式, 同样可以做到这种封装, 不过使用静态成员变量就可以...框架的方式, 你得看你的系统框架能否支持有统一的管理连接的入口 开启事务的标记判断没问题,问题是commit的时候如何判断?我用的是TP。不知道有没有类似的东西。 这个最好去mysql版问一下事务应是可xiang套的 事务是不可以嵌套的。可以用save point达到类似效果 楼主,start的时候可以判断,commit的时候用一样的方法就行了另外,事务如果规划好,应该可以避免这样的事务嵌套发生,这样写,如果函数调用关系复杂了,很容易出错,调试也很麻烦 CKeditor里面写内容怎么获取 ckeditor 换行问题 急求,一段ASP代码转换为PHP 看看你是不是也曾经这样啊 我要判断一个变量是0还是false还是null该怎么做啊? 怎么从文本中取出符合条件的最大几个值 谁有网上调查系统代码,发一个给我,谢谢!! php有没有函数用来显示access数据库类似mysql_list_tables的函数!! PHP在UNIX和LINIX平台上,哪个的性能好些?? 浏览<?phpinfo()?>只能显示源代码 php session_start() 请问如何屏蔽sql错误,谢谢
static $flag;
if(isset($flag)) return ;
mysql_query("BEGIN", $cnn);
//这里可以有一些错误处理机制
$flag = 1;
}
1. 使用mysqli的事务支持...(需要使用mysqli扩展)
$mysqli = new Mysqli($host, $username, $password, $db);
$mysqli->autocommit(false);
//其他处理
2. 框架处理方式(借鉴java开源框架spring的事务处理)
如果请求的处理有统一的入口, 那么在入口处开启事务, 并在对具体业务调用的包装处, 根据异常或错误机制, 进行事务的回滚, 提交的管理.
{
mysql_query("BEGIN"); //开始事务定义
mysql_query("insert into table1 .....");
mysql_query("COMMIT"); //执行事务
define('A',true);
}function b()
{
mysql_query("BEGIN"); //开始事务定义
mysql_query("update table2 .....");
mysql_query("COMMIT"); //执行事务
define('B',true);
}function c()
{
mysql_query("BEGIN"); //开始事务定义
mysql_query("delete table3 ....."); //调用a和b方法
if( !defined('A')) a();
if( !defined('B')) b(); mysql_query("COMMIT"); //执行事务
}c();
第一个方法我没看懂,这个和自动提交有关系吗?PS:我不能要求服务器必须有mysqli扩展,暂时否掉
第二个方法就是最终解决方案,我不知道如何实现spring里的这个东西,类似AOP的东西,求解啊。
除了1/2楼的方法,
你可以用 set autocommit=0 来开始事务,
用 commit; set autocommit=1; 或 rollback; set autocommit=1; 来结束/回滚一个事务这样在a()和b()里可以用 select @@autocommit; 来看是否在事务中间,注意不仅是开始事务的begin前需要判断,更重要的是commit前需要判断,因为重复begin不回出错,提前commit才是出错的直接原因
{
mysql_query("BEGIN"); //开始事务定义
mysql_query("delete table3 ....."); //下边的2个事务实际上是a和b方法里面的
mysql_query("BEGIN"); //开始事务定义
mysql_query("insert into table1 .....");
mysql_query("COMMIT"); //执行事务 mysql_query("BEGIN"); //开始事务定义
mysql_query("update table2 .....");
mysql_query("COMMIT"); //执行事务
mysql_query("COMMIT"); //执行事务
}
现在问题就出来了,里面有3组事务,我的意思是想中间的2组事务,有个监测功能,监测如果上边已经打开了事务,那么就不重复打开了,否则各个事务都生效,那就乱套了,并且失去了事务的意义了。
mysqli的方案和7楼说的是一个意思, 是设置了数据库的autocommit=false. 最终commit/rollback
function begin_transaction($cnn) {
static $flag;
if(isset($flag)) return ;
mysql_query("BEGIN", $cnn);
//这里可以有一些错误处理机制
$flag = 1;
}
1楼我写的这个方法是使用了函数的静态变量来做标记, 对开启事务做一个封装, 这个你可以测试, 是没有问题的...另外, 如果你用面向对象的方式, 同样可以做到这种封装, 不过使用静态成员变量就可以...框架的方式, 你得看你的系统框架能否支持有统一的管理连接的入口
我用的是TP。不知道有没有类似的东西。
事务应是可xiang套的
事务是不可以嵌套的。可以用save point达到类似效果
楼主,start的时候可以判断,commit的时候用一样的方法就行了
另外,事务如果规划好,应该可以避免这样的事务嵌套发生,这样写,如果函数调用关系复杂了,很容易出错,调试也很麻烦