首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >代码点火器事务

代码点火器事务
EN

Stack Overflow用户
提问于 2013-03-05 13:19:17
回答 6查看 64.6K关注 0票数 36

我在使用Codeigniter事务

代码语言:javascript
运行
复制
$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->trans_complete();

这很好,我遇到的问题是,在trans_starttrans_complete中,我调用了其他函数,这些函数处理数据库,因此它们包含插入、更新和一些删除.例:

代码语言:javascript
运行
复制
$this->db->trans_start();
 $this->utils->insert_function($data);
 $this->utils->update_function2($test);
$this->db->trans_complete();

现在,如果这些函数被执行,并且发生了一些错误,CodeIgniter将不会执行回滚。

处理这类问题的最佳方法是什么?

我想到的唯一解决方案是从这些函数和函数add (trans_stattrans_complete)中返回一个错误,如果它返回一个错误测试和do $this->db->trans_rollback

例:

代码语言:javascript
运行
复制
    $this->db->trans_start();
     $result = $this->utils->insert_function($data);
     if($result === false){
       $this->db->trans_rollback();
     }
    $this->db->trans_complete();

有更好的方法吗?

更新1:

根据请求,调用外部函数的示例:

代码语言:javascript
运行
复制
   // insert_function contains

    $rec = array(
        'numero' => $numero,
        'transaction_id' => $id,
        'debit' => $product_taxes['amount_without_taxes'],
        'date' => $data['date_transaction'],
    );
    $this->addExerciceAccountingRecords($rec);

  and addExerciceAccountingRecords contains

   function addExerciceAccountingRecords($records) {
    $this->db->insert('transactions_exercices', $records);
    }
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2016-01-09 15:51:41

使用transactions意味着支持数据库安全地插入数据。因此,在Codeigniter中,我们在 Model 而不是Controller.中编写了每个与数据库相关的函数。在您的第二个代码(不起作用)中,您已经指出了there.(utils).上的模型所以很简单,我肯定这不管用。因为它不是一个与模型和控制器并行的插入数据。事务应该在模型中编码(,我将在我的答案中用模型编写)。

加载这些东西以及

  1. 数据库库
  2. 模型类
  3. URL助手
  4. 会话

假设

在代码中,您使用了$data$test作为数组。因此,我假设有两个数组用于插入和更新数据。

您的数据集

代码语言:javascript
运行
复制
$data = array(
   'title' => 'My title' ,
   'name' => 'My Name' ,
   'date' => 'My date'
);

$id = 007;
$test = array(
   'title' => $title,
   'name' => $name,
   'date' => $date
);

您的代码

代码语言:javascript
运行
复制
$this->db->trans_start(); # Starting Transaction
$this->db->trans_strict(FALSE); # See Note 01. If you wish can remove as well 

$this->db->insert('table_name', $data); # Inserting data

# Updating data
$this->db->where('id', $id);
$this->db->update('table_name', $test); 

$this->db->trans_complete(); # Completing transaction

/*Optional*/

if ($this->db->trans_status() === FALSE) {
    # Something went wrong.
    $this->db->trans_rollback();
    return FALSE;
} 
else {
    # Everything is Perfect. 
    # Committing data to the database.
    $this->db->trans_commit();
    return TRUE;
}

Notes

  1. 默认情况下,Codeigniter在严格模式下运行所有事务。当enabled,严格模式为时,如果您正在运行多个事务组,如果一个组失败,所有组都将回滚。如果严格模式是禁用,则每个组都是独立处理的,意味着一个组的故障不会影响其他组的
票数 47
EN

Stack Overflow用户

发布于 2016-08-08 23:22:39

我试过的更像是个骗局,但对我来说很管用。

代码语言:javascript
运行
复制
$this->db->trans_begin();
  $rst1=  $this->utils->insert_function($data);
  $rst2 =  $this->utils->update_function2($test);
if($this->db->trans_status() === FALSE || !isset($rst1) || !isset($rst2)){
   $this->db->trans_rollback();
}else{
   $this->db->trans_commit();
}
票数 8
EN

Stack Overflow用户

发布于 2013-03-05 18:31:22

我怀疑这个问题与CodeIgniter如何处理对象有关。

如果您访问“创建库”一节下的CI文档,请访问:

libraries.html

请参阅与以下内容有关的一节:

代码语言:javascript
运行
复制
$CI =& get_instance();
$CI->load->helper('url');
$CI->load->library('session');
$CI->config->item('base_url');

在主控制器中,您已经使用自动加载或显式加载类加载/实例化了数据库类。

然后继续打开事务,然后通过utils库访问数据库函数。

但是,一旦在库中使用了$this-db,您实际上正在访问数据库实例的另一个副本,而不是与事务关联的副本。

要访问同一个实例,需要使用get_instance()函数。

我觉得这应该能解决你的问题。您最初的编码风格将功能分离成不同的模块是非常优秀的。您只需了解这个附加的细节。

请试着确认回滚是否如您所期望的那样工作。

代码的核心由以下控制器组成:

代码语言:javascript
运行
复制
$this->db->trans_start();
$this->User_profile_m->create_new_user_profile();
$this->User_profile_m->create_new_user();
$this->db->trans_complete(); 

和一个处理数据持久性的简单模型user_profile_m

代码语言:javascript
运行
复制
function create_new_user()
{
    $data['user_name_usr'] = $this->input->post('user_name');
    $data['create_date_usr'] = NULL;

    $this->db->insert('user_usr', $data);  
}

function create_new_user_profile()
{
    $data['user_name_pro'] = $this->input->post('user_name');
    $data['user_description_pro'] = $this->input->post('user_description');
    $data['create_date_pro'] = NULL;

    $this->db->insert('user_profile_pro', $data);  
}

本质上,演示尝试执行两个插入(两个表中每个插入一个)。如果一个插入失败,另一个将回滚。

我是在CodeIgniter 2.1.3中构建的,我可以通过GitHub使应用程序文件可用,或者将它们压缩并发送给您。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15224826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档