ada*_*fat 17 php mysql codeigniter
我在我的模型中编写了一个函数,用于在我的数据库中插入一个订单.我正在使用事务来确保所有提交,否则它将被回滚.
我的问题是笨没有显示任何数据库错误,但它是回滚事务,但然后返回TRUE
了trans_status
.但是,只有在订单有折扣时才会发生这种情况.如果订单没有折扣,一切都会提交并正常工作.
我目前正在使用CodeIgniter 3.19,PHP(7.2),mySQL(5.7)和Apache 2.4.(在Ubuntu 18.04上工作)
tbl_orders
order_id
并浏览每个订单产品(附件order_id
)并插入产品tbl_order_products
,order_product_id
并将其附加到一组用户出勤选项并插入其中tbl_order_attendance
order_id
)并将其插入tbl_transactions
discount_redeem_count
(可兑换折扣代码的数量)减少1.
[功能]:
public function add_order(Order $order, array $order_products, Transaction $transaction = NULL){
$this->db->trans_start();
$order->create_order_code();
$order_array = $order->create_order_array();
$this->db->insert('tbl_orders', $order_array);
$order_id = $this->db->insert_id();
$new_order = new Order($order_id);
foreach($order_products as $key=>$value){
$order_products[$key]->set_order($new_order);
$order_product_array = $order_products[$key]->create_order_product_array();
$this->db->insert('tbl_order_products', $order_product_array);
$order_product_id = $this->db->insert_id();
$product = $order_products[$key]->get_product();
switch ($product->get_product_class()){
case 'Iteration':
$this->db->select('module_id, webcast_capacity, in_person_capacity');
$this->db->from('tbl_modules');
$this->db->where('iteration_id', $product->get_product_class_id());
$results = $this->db->get()->result_array();
break;
case 'Module':
$this->db->select('module_id, webcast_capacity, in_person_capacity');
$this->db->from('tbl_modules');
$this->db->where('module_id', $product->get_product_class_id());
$results = $this->db->get->result_array();
break;
}
if(!empty($results)){
foreach($results as $result){
$module_id = $result['module_id'];
if($result['webcast_capacity'] !== NULL && $result['in_person_capacity'] !== NULL){
$attendance_method = $order_products[$key]->get_attendance_method();
}elseif($result['webcast_capacity'] !== NULL && $result['in_person_capacity'] === NULL){
$attendance_method = 'webcast';
}elseif($result['webcast_capacity'] === NULL && $result['in_person_capacity'] !== NULL){
$attendance_method = 'in-person';
}
$order_product_attendance_array = array(
'order_product_id' => $order_product_id,
'user_id' => $order_products[$key]->get_customer(true),
'module_id' => $module_id,
'attendance_method' => $attendance_method,
);
$order_product_attendance[] = $order_product_attendance_array;
}
$this->db->insert_batch('tbl_order_product_attendance', $order_product_attendance);
}
if(!empty($order_products[$key]->get_discount())){
$discount = $order_products[$key]->get_discount();
}
}
if(!empty($transaction)){
$transaction->set_order($new_order);
$transaction_array = $transaction->create_transaction_array();
$this->db->insert('tbl_transactions', $transaction_array);
$transaction_id = $this->db->insert_id();
}
if(!empty($discount)){
$this->db->set('discount_redeem_count', 'discount_redeem_count-1', false);
$this->db->where('discount_id', $discount->get_discount_id());
$this->db->update('tbl_discounts');
}
if($this->db->trans_status() !== false){
$result['outcome'] = true;
$result['insert_id'] = $order_id;
return $result;
}else{
$result['outcome'] = false;
return $result;
}
}
Run Code Online (Sandbox Code Playgroud)
当此功能完成了折扣,都trans_complete
和trans_status
回报TRUE
.但是,事务从未提交.
我已经$this->db->error()
在每个查询之后转储了内容,并且在任何查询中都没有错误.
我曾经this->db->last_query()
打印出每个查询,然后在线检查语法,看看是否有任何问题,没有.
我也尝试过使用CodeIgniters手动交易,例如:
[例]
$this->db->trans_begin();
// all the queries
if($this->db->trans_status() !== false){
$this->db->trans_commit();
$result['outcome'] = true;
$result['insert_id'] = $order_id;
return $result;
}else{
$this->db->trans_rollback();
$result['outcome'] = false;
return $result;
}
Run Code Online (Sandbox Code Playgroud)
echo
荷兰国际集团和var_dump
荷兰国际集团所有的回报insert_ids
,他们所有的工作,我也输出的affected_rows()
中的UPDATE
查询,它显示的是1行被更新.但是,仍然没有提交任何内容:[价值转储]
int(10) // order_id
int(10) // order_product_id
array(3) {
["module_id"]=> string(1) "1"
["webcast_capacity"]=> string(3) "250"
["in_person_capacity"]=> string(3) "250" } // $results array (modules)
array(1) {
[0]=> array(4) {
["order_product_id"]=> int(10
["user_id"]=> string(1) "5"
["module_id"]=> string(1) "1"
["attendance_method"]=> string(7) "webcast" } } // order_product_attendance array
int(9) // transaction_id
int(1) // affected rows
string(99) "UPDATE `tbl_discounts`
SET discount_redeem_count = discount_redeem_count- 1
WHERE `discount_id` = 1" // UPDATE query
Run Code Online (Sandbox Code Playgroud)
- 我也尝试用UPDATE
一个完全不同的查询替换最后一个查询,该查询试图用不同的值更新不同的表.该查询也不起作用,这让我觉得我在事务中遇到某种内存限制.但是,在监控mysqld
流程时,它们似乎都没有出现尖峰或有困难.
我们尝试设置log_threshold
为4,并查看了CodeIgniter日志文件,其中没有显示回滚历史记录.
我们检查了mySQL查询日志:
[查询日志]
2018-12-03T15:20:09.452725Z 3 Query UPDATE `tbl_discounts` SET discount_redeem_count = discount_redeem_count-1 WHERE `discount_id` = '1'
2018-12-03T15:20:09.453673Z 3 Quit
Run Code Online (Sandbox Code Playgroud)
它显示QUIT
在UPDATE
查询后直接发送命令.这将启动回滚,但是trans_status
返回TRUE
.
我也改变my.cnf
了mySQL的文件来拥有innodb_buffer_pool_size=256M
和innodb_log_file_size=64M
.结果没有变化.
UPDATE
查询以使用simple_query()
而不是使用CodeIgniter的Query Builder类中的默认方法:[简单查询]
if(!empty($discount)){
$this->db->simple_query('UPDATE `tbl_discounts` SET '.
'discount_redeem_count = discount_redeem_count-1 WHERE '.
'`discount_id` = \''.$discount['discount_id'].'\'');
}
Run Code Online (Sandbox Code Playgroud)
然而,这种产生不会对结果产生任何不同的影响.
如果你有一个我还没有尝试过的想法,或者需要我提供更多信息,请发表评论,我会及时回复.
如果我的交易都没有提交,为什么要trans_status
返回TRUE
?
为了尝试为用户提供一些清晰度,现在只是找到这个问题,该帖子的最新更新将以斜体显示*
我发现了问题。我想对所有尝试提供帮助的人表示感谢,但这是我的错。
在调用此函数的Controller方法的前面,我调用了另一个启动事务的函数。该交易从未关闭,因此继续进行新交易。
因为没有提交事务,并且没有错误,所以我找不到任何错误或任何回滚历史记录。但是,一旦我关闭了先前的交易,一切就开始了。
在mySQL查询日志,mySQL错误日志或CodeIgniter错误日志中没有证据表明存在任何问题。我只能通过慢慢阅读整个mySQL查询日志来找到此问题。
对于遇到此问题的任何人:检查您的其他事务并确保它们都已关闭。