×

thinkphpstarttrans

thinkphpstarttrans的简单介绍

admin admin 发表于2023-04-04 07:00:09 浏览42 评论0

抢沙发发表评论

本文目录一览:

请教大神 ThinkPHP5 的事务回滚问题

请看手册:

使用 transaction 方法操作数据库事务,当发生异常会自动回滚,例如:

自动控制事务处理

Db::transaction(function(){

Db::table('think_user')-find(1);

Db::table('think_user')-delete(1);

});

也可以手动控制事务,例如:

// 启动事务

Db::startTrans();

try{

Db::table('think_user')-find(1);

Db::table('think_user')-delete(1);

// 提交事务

Db::commit();

} catch (\Exception $e) {

// 回滚事务

Db::rollback();

}

注意在事务操作的时候,确保你的数据库连接是相同的。

thinkphp对数据库操作有哪些内置函数

8.4.4 Model类

getModelName() 获取当前Model的名称

getTableName() 获取当前Model的数据表名称

switchModel(type,vars=array()) 动态切换模型

table() 设置当前操作的数据表

field() 设置要查询的数据字段

where() 设置查询或者操作条件

data(data) 设置数据对象

order(order) 设置排序

limit(limit) 查询限制

page(page) 查询分页

join(join) 进行JOIN查询

having(having) 进行having查询

group(group) 进行group查询

lock(lock) 查询锁定

distinct(distinct) 唯一性查询

count(field) 记录统计

sum(field) 总数查询

min(field) 最小值查询

max(field) 最大值查询

avg(field) 平均值查询

_initialize() 模型初始化方法

_facade(data) 对保存到数据库的数据进行处理

_before_write(data) 写入数据前的回调方法 包括新增和更新

add(data='',options=array()) 新增数据

_before_insert(data,options) 写入数据前的回调方法

_after_insert(data,options) 写入数据后的回调方法

selectAdd(fields='',table='',options=array()) 通过Select方式添加记录

save(data='',options=array()) 更新数据到数据库

_before_update(data,options) 更新数据前的回调方法

_after_update(data,options) 更新成功后的回调方法

delete(options=array()) 删除数据

_after_delete(data,options) 删除成功后的回调方法

select(options=array()) 查询数据集

_after_select(resultSet,options) 查询成功后的回调方法

findAll(options=array()) select方法的别名

_options_filter(options) 表达式过滤回调方法

find(options=array()) 查询数据

_after_find(result,options) 查询成功的回调方法

setField(field,value,condition='') 设置记录的某个字段值

setInc(field,condition='',step=1) 字段值增长

setDec(field,condition='',step=1) 字段值减少

getField(field,condition='',sepa=' ') 获取某个字段值

create(data='',type='') 创建数据对象

autoCheckToken(data) 表单令牌验证

query(sql) 执行原生SQL查询

execute(sql='') 执行原生SQL操作

startTrans() 启动事务

commit() 提交事务

rollback() 事务回滚

getError() 获取模型的错误信息

getDbError() 获取数据库的错误信息

getLastInsID() 获取最后执行的SQL语句

getPk() 获取主键名称

getDbFields() 获取数据表的字段信息

regex(value,rule) 使用正则验证数据

setProperty(name,value) 设置模型的属性值

2.1版新增方法:

db(linkNum,config='') 切换当前数据库连接

高级模型类AdvModel

topN(count,options=array()) 查询满足条件的前N个记录

getN(position=0,options=array()) 查询符合条件的第N条记录

0 表示第一条记录 -1 表示最后一条记录

first(options=array()) 获取满足条件的第一条记录

last(options=array()) 获取满足条件的最后一条记录

returnResult(data,type='') 返回指定的数据类型

setLazyInc(field,condition='',step=1,lazyTime=0) 字段值延迟增长

setLazyDec(field,condition='',step=1,lazyTime=0) 字段值延迟减少

addConnect(config,linkNum=NULL) 增加数据库连接

delConnect(linkNum) 删除数据库连接

closeConnect(linkNum) 关闭数据库连接

switchConnect(linkNum,name='') 切换数据库连接

patchQuery(sql=array()) 批处理执行SQL语句

getPartitionTableName(data=array()) 得到分表的的数据表名

Thinkphp怎么批量更新数据

thinkphp批量更新数据可以参考如下三种方法:

方法一:

//批量修改 data二维数组 field关键字段 参考ci 批量修改函数 传参方式

function batch_update($table_name='',$data=array(),$field=''){

if(!$table_name||!$data||!$field){

return false;

}else{

$sql='UPDATE '.$table_name;

}

$con=array();

$con_sql=array();

$fields=array();

foreach ($data as $key = $value) {

$x=0;

foreach ($value as $k = $v) {

if($k!=$field!$con[$x]$x==0){

$con[$x]=" set {$k} = (CASE {$field} ";

}elseif($k!=$field!$con[$x]$x0){

$con[$x]=" {$k} = (CASE {$field} ";

}

if($k!=$field){

$temp=$value[$field];

$con_sql[$x].= " WHEN '{$temp}' THEN '{$v}' ";

$x++;

}

}

$temp=$value[$field];

if(!in_array($temp,$fields)){

$fields[]=$temp;

}

}

$num=count($con)-1;

foreach ($con as $key = $value) {

foreach ($con_sql as $k = $v) {

if($k==$key$key$num){

$sql.=$value.$v.' end),';

}elseif($k==$key$key==$num){

$sql.=$value.$v.' end)';

}

}

}

$str=implode(',',$fields);

$sql.=" where {$field} in({$str})";

$res=M($table_name)-execute($sql);

return $res;

}

//测试

function test(){

$update_array=array();

for ($i=2; $i 7 ; $i++) {

$data=array();

$data['id']=$i;

$data['memeber_type']=2;

$data['memeber_type_state']=1;

$update_array[]=$data;

}

$res=$this-batch_update('yl_member',$update_array,id);

var_dump($res);

}

方法二:

即是循环一条一条的更新记录。一条记录update一次,这样性能很差,也很容易造成阻塞。

那么能不能一条sql语句实现批量更新呢?mysql并没有提供直接的方法来实现批量更新,但是可以用点小技巧来实现。

UPDATE categories

SET display_order = CASE id

WHEN 1 THEN 3

WHEN 2 THEN 4

WHEN 3 THEN 5

END

WHERE id IN (1,2,3)

这句sql的意思是,更新display_order 字段,如果id=1 则display_order 的值为3,如果id=2 则 display_order 的值为4,如果id=3 则 display_order 的值为5。-thinkphpstarttrans

即是将条件语句写在了一起。

这里的where部分不影响代码的执行,但是会提高sql执行的效率。确保sql语句仅执行需要修改的行数,这里只有3条数据进行更新,而where子句确保只有3行数据执行。

如果更新多个值的话,只需要稍加修改:

UPDATE categories

SET display_order = CASE id

WHEN 1 THEN 3

WHEN 2 THEN 4

WHEN 3 THEN 5

END,

title = CASE id

WHEN 1 THEN 'New Title 1'

WHEN 2 THEN 'New Title 2'

WHEN 3 THEN 'New Title 3'

END

WHERE id IN (1,2,3)

实际运用

$display_order = array(

1 = 4,

2 = 1,

3 = 2,

4 = 3,

5 = 9,

6 = 5,

7 = 8,

8 = 9

);

$ids = implode(',', array_keys($display_order));

$sql = "UPDATE categories SET display_order = CASE id ";

foreach ($display_order as $id = $ordinal) {

$sql .= sprintf("WHEN %d THEN %d ", $id, $ordinal);

}

$sql .= "END WHERE id IN ($ids)";

echo $sql;

方法二不建议使用。

方法三:

/*

* @param $saveWhere :想要更新主键ID数组

* @param $saveData :想要更新的ID数组所对应的数据

* @param $tableName : 想要更新的表明

* @param $saveWhere : 返回更新成功后的主键ID数组

* */

public function saveAll($saveWhere,$saveData,$tableName){

if($saveWhere==null||$tableName==null)

return false;

//获取更新的主键id名称

$key = array_keys($saveWhere)[0];

//获取更新列表的长度

$len = count($saveWhere[$key]);

$flag=true;

$model = isset($model)?$model:M($tableName);

//开启事务处理机制

$model-startTrans();

//记录更新失败ID

$error=[];

for($i=0;$i$len;$i++){

//预处理sql语句

$isRight=$model-where($key.'='.$saveWhere[$key][$i])-save($saveData[$i]);

if($isRight==0){

//将更新失败的记录下来

$error[]=$i;

$flag=false;

}

//$flag=$flag$isRight;

}

if($flag ){

//如果都成立就提交

$model-commit();

return $saveWhere;

}elseif(count($error)0count($error)$len){

//先将原先的预处理进行回滚

$model-rollback();

for($i=0;$icount($error);$i++){

//删除更新失败的ID和Data

unset($saveWhere[$key][$error[$i]]);

unset($saveData[$error[$i]]);

}

//重新将数组下标进行排序

$saveWhere[$key]=array_merge($saveWhere[$key]);

$saveData=array_merge($saveData);

//进行第二次递归更新

$this-saveAll($saveWhere,$saveData,$tableName);

return $saveWhere;

}

else{

//如果都更新就回滚

$model-rollback();

return false;

}

}

在测试方法中调用:

public function test(){

//要更新的数据表的主键数组

$where['ID']=array(70,73,74,80,83);

//ID主键数组对应的待更新数据

$save=array(

array('School'='DK Univisity01','isExport'=0),

array('School'='DK Univisity02','isExport'=0),

array('School'='DK Univisity03','isExport'=0),

array('School'='DK Univisity04','isExport'=0),

array('School'='','isExport'=0),

// array('School'=' Univisity05','isExport'=0),

);

$f=$this-saveAll($where,$save,'want');

if(count($f['ID'])0){

//返回更新成功的ID数组

echo "This is success :/br";

dump($f);

echo 'ok';

}else{

//更新失败操作

echo "This is failed :/br";

dump($f);

echo 'error';

}

}

thinkphp 里面的事务值支持一张表吗

不只是支持一张表哦,可以同时操作多张表也就是多个模型的。

M('User')-startTrans();

M('UserDetail')-startTrans();

M('User')-commit();

M('UserDetail')-commit();

需要注意的是startTrans()一开始执行就会将之前的事务全部提交,所以必须要把事务提前开启了再操作。