Dar*_*gor 5 database activerecord transactions codeigniter insertion
我在CodeIgniter中运行一个小方法来在数据库中插入一些行(同一个表).我想看看在事务中哪个插入失败(通过返回标题数组).我的代码是:
$failure = array(); //the array where we store what failed
$this->db->trans_start();
foreach ($data as $ressourceCsv){ //data is an array of arrays to feed the database
$this->ajout_ressource($ressourceCsv); //method to insert (basically, just an insert with active record)
if (($this->db->_error_message())!=null) {
$failure[] = $ressourceCsv['title'];
}
}
$this->db->trans_complete();
return $failure;
Run Code Online (Sandbox Code Playgroud)
事实是,如果我不使它成为一个事务(没有$ this-> db-> trans _...),它完美地工作,我有一个包含几个标题的数组.但是对于事务,数组包含自第一个错误以来的所有标题.有没有办法从插入中获取导致事务回滚的标题?
我也尝试过:
$failure = array(); //the array where we store what failed
$this->db->trans_start();
foreach ($data as $ressourceCsv){ //data is an array of arrays to feed the database
if (!$this->ajout_ressource($ressourceCsv)) { //active record insertion return true
$failure[] = $ressourceCsv['title']; // if successful
}
}
$this->db->trans_complete();
return $failure;
Run Code Online (Sandbox Code Playgroud)
我相信一旦事务内部发生错误,您必须回滚才能进行更多的数据库修改。这可以解释您所看到的行为。出现第一个错误后,事务将“中止”,并且您继续循环,导致每个后续 SQL 命令也失败。这可以如下说明:
db=# select * from test1;
id | foo | bar
----+-----+-----
(0 rows)
db=# begin;
BEGIN
db=# insert into test1 (foo, bar) values (1, 'One');
INSERT 0 1
db=# insert into test1 (foo, bar) values (Oops);
ERROR: column "oops" does not exist
LINE 1: insert into test1 (foo, bar) values (Oops);
^
db=# insert into test1 (foo, bar) values (2, 'Two');
ERROR: current transaction is aborted, commands ignored until end of transaction block
db=# select * from test1;
ERROR: current transaction is aborted, commands ignored until end of transaction block
db=# commit;
ROLLBACK
ace_db=# select * from test1;
id | foo | bar
----+-----+-----
(0 rows)
db=#
Run Code Online (Sandbox Code Playgroud)
请注意,如果出现错误,“提交”似乎会执行“回滚”(这不是拼写错误。)
另外顺便说一句:用于$this->db->trans_status() === FALSE检查事务期间是否有错误。
更新:这里有一些(未经测试的)代码在事务中执行此操作,以便在您准备好之前其他人看不到插入:
$failure = array(); //the array where we store what failed
$done = false;
do {
$this->db->trans_begin();
foreach ($data as $key => $ressourceCsv){ //data is an array of arrays to feed the database
$this->ajout_ressource($ressourceCsv); //method to insert (basically, just an insert with active record)
if ($this->db->trans_status() === false) { // an insert failed
$failure[] = $ressourceCsv['title']; // save the failed title
unset($data[$key]); // remove failed insert from data set
$this->db->trans_rollback(); // rollback the transaction
break; // retry the insertion
}
}
$done = true; // completed without failure
} while (count($data) and ! $done); // keep going until no data or success
/*
* Two options (uncomment one):
* 1. Commit the successful inserts even if there were failures.
$this->db->trans_commit();
* 2. Commit the successful inserts only if no failures.
if (count($failure)) {
$this->db->trans_rollback();
} else {
$this->db->trans_commit();
}
*/
return $failure;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3924 次 |
| 最近记录: |