function foo($db, $data) {
$db->beginTransaction();
foreach ($data as $row) {
$db->insert($row);
}
$db->commit();
}
(David Abrahams)
function foo($db, $data) {
$db->beginTransaction();
try {
foreach ($data as $row) {
$db->insert($row);
}
} catch(\Exception $e) {
$db->rollback();
throw $e;
}
$db->commit();
}
function runInTransaction($db, $cb) {
$db->beginTransaction();
try {
$cb();
} catch(\Exception $e) {
$db->rollback();
throw $e;
}
$db->commit();
}
function foo($db, $data) {
runInTransaction($db, function ()
use($db, $data) {
foreach ($data as $row) {
$db->insert($row);
}
});
}
function foo($db, $data) {
$transaction = new Transaction($db);
foreach ($data as $row) {
$db->insert($row);
}
$transaction->commit();
}
class Transaction {
private $db;
private $success = false;
function __construct($db) {
$this->db = $db;
$db->begin();
}
function commit() {
$this->db->commit();
$this->success = true;
}
function __destruct() {
if (!$this->success) {
$this->db->rollback();
}
}
}
function foo() {
$a = new A();
$b = $a;
}
function a() {
try {
b();
} catch (\Exception $e) {
Logger::error($e);
}
}
function b() {
$o = new O();
c();
}
function c() {
throw new \Exception();
}
echo expensiveCalculation(); // works
$a = expensiveCalculation();
unset($a); // will complain
class EnforceUsage {
private $value;
private $used = false;
function __construct($value) {
$this->value = $value;
}
function __toString() {
$this->used = true;
return (string)$this->value;
}
function __destruct() {
if (!$this->used) {
Logger::notice("Return value not used");
}
}
}
(no Java invention - at leat Object Pascal and Modula had finally before)
void foo(Database db, Object data) {
boolean success = false;
db.beginTransaction();
try {
db.insert(data);
db.commit();
success = true;
} finally {
if (!success) {
db.rollback();
}
}
}
http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
try (Transaction t =
new Transaction(db) {
db.insert();
t.commit();
}
Know Your Language!
Johannes Schlüter
johannes@php.net
@johannescode
https://slides.com/johannes4321/froscon15