php - usadas - La transacción no funciona para las funciones secundarias
manejo de funciones en php (5)
Utilicé DB::beginTransaction()
en Laravel, pero funciona solo para cambios de bases de datos que se realizan en la función principal, pero no para subfunciones.
Código de función principal:
try {
DB::beginTransaction();
$data = array(
''id'' => Input::get(''id''),
''task_title'' => Input::get(''task_title''),
);
DB::table(''task'')->insert($data);
$id = DB::getPdo()->lastInsertId();
// Add Actionees
if (!$this->addActionees(Input::get(''actionees''), $id)) {
DB::rollback();
return Response::json(false);
}
DB::commit();
return Response::json(true);
} catch (Exception $ex) {
DB::rollback();
return Response::json($ex);
}
Código de función secundaria:
private function addActionees($actionees, $id, $status) {
try {
DB::table(''task_assignee_user'')->where(''task_id'', $id)->delete();
foreach ($actionees as $act) {
$actAdd = array(
''task_id'' => $id,
''user_id'' => $act->user_id,
);
DB::table(''task_assignee'')->insert($actAdd);
}
return True;
} catch (Exception $ex) {
return FALSE;
}
}
Por lo tanto, en el ejemplo anterior, los cambios que se realizan en las funciones addActionees()
no se retrotraen, en la función addActionees()
se eliminará todo el registro contra ID antes de insertar nuevos registros. Si se encuentra una excepción, entonces quiero revertir estos cambios.
En la función principal: beginTransaction
bofore try{
DB::beginTransaction();
try {
$data = array(
...
No debe detectar la excepción en el método addActionees (). Simplemente déjalo tirado y el bloque try-catch externo lo manejará:
Código de función principal:
try {
DB::beginTransaction();
$data = array(
''id'' => Input::get(''id''),
''task_title'' => Input::get(''task_title''),
);
DB::table(''task'')->insert($data);
$id = DB::getPdo()->lastInsertId();
// Add Actionees
$this->addActionees(Input::get(''actionees''), $id);
DB::commit();
return Response::json(true);
} catch (Exception $ex) {
DB::rollback();
return Response::json($ex);
}
Código de función secundaria:
private function addActionees($actionees, $id, $status) {
DB::table(''task_assignee_user'')->where(''task_id'', $id)->delete();
foreach ($actionees as $act) {
$actAdd = array(
''task_id'' => $id,
''user_id'' => $act->user_id,
);
DB::table(''task_assignee'')->insert($actAdd);
}
}
Su único funciona cuando uso DB::beginTransaction()
en sub función, pero no es una respuesta a mi pregunta:
Código de función principal:
try {
DB::beginTransaction();
$data = array(
''id'' => Input::get(''id''),
''task_title'' => Input::get(''task_title''),
);
DB::table(''task'')->insert($data);
$id = DB::getPdo()->lastInsertId();
// Add Actionees
if (!$this->addActionees(Input::get(''actionees''), $id)) {
DB::rollback();
return Response::json(false);
}
DB::commit();
return Response::json(true);
} catch (Exception $ex) {
DB::rollback();
return Response::json($ex);
}
Código de función secundaria:
private function addActionees($actionees, $id, $status) {
DB::beginTransaction();
try {
DB::table(''task_assignee_user'')->where(''task_id'', $id)->delete();
foreach ($actionees as $act) {
$actAdd = array(
''task_id'' => $id,
''user_id'' => $act->user_id,
);
DB::table(''task_assignee'')->insert($actAdd);
}
DB::commit();
return True;
} catch (Exception $ex) {
DB::rollback();
return FALSE;
}
}
Intenta usar la transacción a través del flujo de esta manera:
DB::beginTransaction();
try {
$data = array(
''id'' => Input::get(''id''),
''task_title'' => Input::get(''task_title''),
);
DB::table(''task'')->insert($data);
$id = DB::getPdo()->lastInsertId();
// Add Actionees
$this->addActionees(Input::get(''actionees''), $id);
} catch (Exception $ex) {
DB::rollBack();
return Response::json($ex);
}
DB::commit();
return Response::json(true);
private function addActionees($actionees, $id, $status) {
DB::table(''task_assignee_user'')->where(''task_id'', $id)->delete();
foreach ($actionees as $act) {
$actAdd = array(
''task_id'' => $id,
''user_id'' => $act->user_id,
);
DB::table(''task_assignee'')->insert($actAdd);
}
}
- Comience la transacción.
- Ejecutar operaciones CRUD.
- Captura la excepción y revierte la transacción.
- Si las operaciones ejecutadas son fluidas, comprometa la transacción.
Editar:
addActionees
siempre devuelve verdadero porque el método delete()
no lanza una excepción mientras se ejecuta. Por lo tanto $this->addActionees(Input::get(''actionees''), $id)
siempre devuelve verdadero. Lancemos una excepción de forma manual:
private function addActionees($actionees, $id, $status) {
$deleteResult = DB::table(''task_assignee_user'')->where(''task_id'', $id)->delete();
foreach ($actionees as $act) {
$actAdd = array(
''task_id'' => $id,
''user_id'' => $act->user_id,
);
DB::table(''task_assignee'')->insert($actAdd);
}
if ($deleteResult == 0) {
throw new Exception(''Delete failed'');
}
}
Si envuelve toda la transacción dentro de un cierre, se encargará de todo por usted :
public mainFunction()
{
try {
DB::transaction(function() {
$id = DB::table(''task'')->insertGetId([''id'' => Input::get(''id''),
''task_title'' => Input::get(''task_title'')]);
DB::table(''task_assignee_user'')->where(''task_id'', $id)->delete();
foreach(Input::get(''actionees'') as $act) {
DB::table(''task_assignee'')->insert([''task_id'' => $id,
''user_id'' => $act->user_id]);
}
});
} catch (/Exception $e) {
return Response::json($e);
}
return Response::json(true);
}
ps También refactoré tu código ya que me estaba volviendo loco. Esto debería funcionar, pero no lo he probado, pero se entiende la idea general.