【问题标题】:laravel insert data using DB:Transactionlaravel 使用 DB:Transaction 插入数据
【发布时间】:2018-03-13 17:33:51
【问题描述】:

我有简单的 Laravel 上传、插入/更新。

我有将 csv 文件上传到我的目录的 ajax..

$.ajax({
    url:'uploadExcel',
    data: new FormData($("#uploadForm")[0]),
    headers: {
        'X-CSRF-TOKEN' : $('meta[name="_token"]').attr('content')
    },
    // dataType:'json',
    async: true,
    type:'post',
    cache: false,
    processData: false,
    contentType: false, 
    success: function(){
        //chunk data from CSV
    },
    error: function(data){
        var errors = data.responseJSON;
        console.log(errors);
    },
    complete:function(completeData){
        console.log(completeData);
    }
});

成功后,我将 csv 中的数据分块。它使用link 成功分块,现在我使用DB::transaction(function() {}); 插入数据库。但现在我想使用DB:COMMITDB:ROLLBACK...

知道我该怎么做吗?

对于DB:COMMIT,我有一个提交最后一个事务的按钮。

对于DB:ROLLBACK,我有一个按钮可以回滚上次事务中的所有内容。

注意:我正在为此做 ajax,但它不起作用。

更新:我是手动的。 我有beginTransaction的函数

DB::beginTransaction();
    foreach($results as $row){
        $item = new items;
        $selectQuery = DB::table('items')
            ->where('title', '=', $row["1"])
            ->where('description', '=', $row["2"])
            ->get();

        if (count($selectQuery) > 0) {
            // update
            DB::table('items')
                ->where('title', '=', $row["1"])
                ->where('description', '=', $row["2"])
                ->update([
                    "title" => $row["1"],
                    "description" => $row["2"]
                ]);

        } else {
            //insert
            $item->title = $row["1"];
            $item->description = $row["2"];
            $item->save();
        } 
    }

我的控制器中的第二个函数是DB::commit();,第三个函数是DB:rollback();

此方法不保存 csv 中的任何数据,并且回滚和提交不起作用。有什么想法吗?

【问题讨论】:

  • 你不应该把它包装在try-catch 中吗?将DB::beginTransaction()DB::commit() 放在try 块中,将DB::rollback() 放在catch 块中。为什么要有回滚和提交按钮?
  • @Doom5 因为我希望第一个检查 csv 中的数据是否正确,为此我希望第一个将其保存到数据库并为 commit() 和 rollback() 提供 2 个单独的按钮
  • 那么你应该先验证它,然后再将它保存到数据库中。此外,您似乎正在执行更新或插入保存模式。
  • Offtopic,但无论如何选择要更新的行是不好的做法,并且会降低性能。只需 $updated = DB::table...->update(...);如果没有更新行,则插入。
  • @AiXEn 你能确认你的函数是否抛出任何错误吗?

标签: php ajax laravel


【解决方案1】:

如果你将闭包传递给DB::transaction(),Laravel 将自动调用DB::commmit,如果没有成功执行闭包,则自动调用DB::rollBack,如果抛出异常。

如果您想控制它(手动方式),请使用DB::beginTransaction()

例如:

DB::beginTransaction();
try{
   ...

   DB::commit();
}catch(\Exception $e){
   // echo $e->getMessage();
   DB::rollBack();
}

【讨论】:

  • 我以手动方式使用DB::beginTransaction(),所以我在控制器中有3个功能第一个功能是beginTransaction(),第二个功能是Commit,第三个功能是Rollback和我仍然无法回滚最后一个事务...
【解决方案2】:

Laravel:数据库事务

如果您在 DB 门面上使用事务方法并且如果在事务关闭中抛出异常,则事务将自动回滚。如果闭包成功执行,事务将自动提交。使用事务方法时无需担心手动回滚或提交:

DB::transaction(function () {
    //your queries
});

手动使用事务

如果您想手动开始事务并完全控制回滚和提交,您可以使用 DB 外观上的 beginTransaction 方法:

DB::beginTransaction();

您可以通过rollBack方法回滚事务:

DB::rollBack();

最后,您可以通过 commit 方法提交事务:

DB::commit();

更多详情请查看文档:https://laravel.com/docs/5.2/database#database-transactions

【讨论】:

    【解决方案3】:

    试试这个。为此在您的config/database.php 中定义一个单独的连接,比如说temporary_connection
    现在,在您的控制器中,不要在DB(它使用默认连接)上使用事务,而是使用新创建的连接。

    你的方法包含beginTransaction:

    $connection = DB::connection('temporary_connection');
    $connection->beginTransaction();
    //rest of the code
    

    你的方法包含rollback:

    $connection = DB::connection('temporary_connection');
    $connection->rollback();
    //rest of the code
    

    你的方法包含commit:

    $connection = DB::connection('temporary_connection');
    $connection->commit();
    //rest of the code
    

    【讨论】:

      猜你喜欢
      • 2014-12-17
      • 2019-06-24
      • 1970-01-01
      • 1970-01-01
      • 2021-08-14
      • 2015-09-19
      • 1970-01-01
      • 2020-12-31
      • 2016-07-03
      相关资源
      最近更新 更多