PHPackages                             gielfeldt/transactionalphp - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. gielfeldt/transactionalphp

ActiveLibrary[Database &amp; ORM](/categories/database)

gielfeldt/transactionalphp
==========================

Transactional PHP.

0.8.0(9y ago)01.5kMITPHPPHP &gt;=5.4.0

Since May 21Pushed 9y ago1 watchersCompare

[ Source](https://github.com/gielfeldt/transactionalphp)[ Packagist](https://packagist.org/packages/gielfeldt/transactionalphp)[ Docs](https://github.com/gielfeldt/transactionalphp)[ RSS](/packages/gielfeldt-transactionalphp/feed)WikiDiscussions master Synced today

READMEChangelogDependenciesVersions (9)Used By (0)

Transactional PHP
=================

[](#transactional-php)

[![Build Status](https://camo.githubusercontent.com/51441e102e9911dfa6ece4707aca484f6c14722dc3db83ab7206d86ee634af98/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6769656c66656c64742f7472616e73616374696f6e616c7068702f6261646765732f6275696c642e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/gielfeldt/transactionalphp/build-status/master)[![Test Coverage](https://camo.githubusercontent.com/41a4e7b67e820e46b9515b0b4c0b1b2fed7de6b2e41291bba732635a922fd8a4/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f6769656c66656c64742f7472616e73616374696f6e616c7068702f6261646765732f636f7665726167652e737667)](https://codeclimate.com/github/gielfeldt/transactionalphp/coverage)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/d86f182d139f3a697baa7ef8a2956a8061c1800234abcf4fbeeede2225228157/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6769656c66656c64742f7472616e73616374696f6e616c7068702f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/gielfeldt/transactionalphp/?branch=master)[![Code Climate](https://camo.githubusercontent.com/b534b3ff45b8349fa4c2874fa36f296388ea5a2ba43acdde4528cda910a401b5/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f6769656c66656c64742f7472616e73616374696f6e616c7068702f6261646765732f6770612e737667)](https://codeclimate.com/github/gielfeldt/transactionalphp)

[![Latest Stable Version](https://camo.githubusercontent.com/8336f8b48080c36ca3aaa2d32a0fc58c801b441ac1dbb2338de5bc82ad62f295/68747470733a2f2f706f7365722e707567782e6f72672f6769656c66656c64742f7472616e73616374696f6e616c7068702f762f737461626c652e737667)](https://packagist.org/packages/gielfeldt/transactionalphp)[![Latest Unstable Version](https://camo.githubusercontent.com/2aa2c79f16f1d573cabb9b5a6784987cc6b40742a301584ed1b715b6080aa2aa/68747470733a2f2f706f7365722e707567782e6f72672f6769656c66656c64742f7472616e73616374696f6e616c7068702f762f756e737461626c652e737667)](https://packagist.org/packages/gielfeldt/transactionalphp)[![License](https://camo.githubusercontent.com/bd2d6af2272d0bd2e39050c09b2b7858a548dc6811720cfe0e7122a2723a057e/68747470733a2f2f706f7365722e707567782e6f72672f6769656c66656c64742f7472616e73616374696f6e616c7068702f6c6963656e73652e737667)](https://github.com/gielfeldt/transactionalphp/blob/master/LICENSE.md)[![Total Downloads](https://camo.githubusercontent.com/1e03dc015e0568acb4455a478f12b7d575cfbc9964acdca3cc297728b1f499b9/68747470733a2f2f706f7365722e707567782e6f72672f6769656c66656c64742f7472616e73616374696f6e616c7068702f646f776e6c6f6164732e737667)](https://packagist.org/packages/gielfeldt/transactionalphp)

Installation
------------

[](#installation)

To install the Transactional PHP library in your project using Composer, first add the following to your `composer.json`config file.

```
{
    "require": {
        "gielfeldt/transactionalphp": "^0.8"
    }
}
```

Then run Composer's install or update commands to complete installation. Please visit the [Composer homepage](http://getcomposer.org) for more information about how to use Composer.

### Transactional PHP

[](#transactional-php-1)

This class allows to buffer php code in a simulated transaction, thereby postponing the execution of the code until a commit occurs.

#### Motivation

[](#motivation)

1. Problem of keeping external cache in sync with the database, see the Drupal module Cache Consistent.

#### Using the Transactional PHP library

[](#using-the-transactional-php-library)

##### Example 1 - Simple

[](#example-1---simple)

```
namespace Gielfeldt\TransactionalPHP\Example;

require 'vendor/autoload.php';

use Gielfeldt\TransactionalPHP\Connection;

$connection = new Connection();

// Start outer transaction.
$connection->startTransaction();

$connection->onCommit(function () {
    print "THIS WILL BE PRINTED, BECAUSE THIS WILL BE COMMITTED\n";
});

// Start inner transaction.
$connection->startTransaction();

$connection->onCommit(function () {
    print "THIS WILL NOT BE PRINTED, BECAUSE THIS WILL BE ROLLED BACK\n";
});

// Rollback inner transaction.
$connection->rollbackTransaction();

// Commit inner transaction.
$connection->commitTransaction();
```

##### Example 2 - Commit and rollback

[](#example-2---commit-and-rollback)

```
namespace Gielfeldt\TransactionalPHP\Example;

require 'vendor/autoload.php';

use Gielfeldt\TransactionalPHP\Connection;
use Gielfeldt\TransactionalPHP\Operation;

$connection = new Connection();

$operation = new Operation();
$operation->onCommit(function () {
    print "THIS WILL BE PRINTED IMMEDIATELY, BECAUSE NO TRANSACTION HAS BEGUN\n";
})
->onRollback(function () {
    print "THIS WILL NEVER BE PRINTED, BECAUSE NO TRANSACTION HAS BEGUN\n";
});
$connection->addOperation($operation);

// Start outer transaction.
$connection->startTransaction();

$operation = new Operation();
$operation->onCommit(function () {
    print "THIS WILL BE PRINTED, BECAUSE THIS WILL BE COMMITTED\n";
})
->onRollback(function () {
    print "THIS WILL NEVER BE PRINTED, BECAUSE THIS WILL BE COMMITTED\n";
});
$connection->addOperation($operation);

// Start inner transaction.
$connection->startTransaction();

$operation = new Operation();
$operation->onCommit(function () {
    print "THIS WILL NOT BE PRINTED, BECAUSE THIS WILL BE ROLLED BACK\n";
})
->onRollback(function () {
    print "THIS WILL BE PRINTED, BECAUSE THIS WILL BE ROLLED BACK\n";
});
$connection->addOperation($operation);

// Rollback inner transaction.
$connection->rollbackTransaction();

// Commit inner transaction.
$connection->commitTransaction();
```

##### Example 3 - Using the indexer

[](#example-3---using-the-indexer)

```
namespace Gielfeldt\TransactionalPHP\Example;

require 'vendor/autoload.php';

use Gielfeldt\TransactionalPHP\Connection;
use Gielfeldt\TransactionalPHP\Indexer;
use Gielfeldt\TransactionalPHP\Operation;

$connection = new Connection();
$indexer = new Indexer($connection);

$operation = (new Operation())
    ->onCommit(function () {
        print "THIS WILL BE PRINTED IMMEDIATELY, BECAUSE NO TRANSACTION HAS BEGUN\n";
    })
    ->onRollback(function () {
        print "THIS WILL NEVER BE PRINTED, BECAUSE NO TRANSACTION HAS BEGUN\n";
    })
    ->onBuffer(function ($operation) use ($indexer) {
        print "INDEXING test1\n";
        $indexer->index($operation, 'test1');
    })
    ->setMetadata('value', 'test1');
$connection->addOperation($operation);

// Start outer transaction.
$connection->startTransaction();

$operation = (new Operation())
    ->onCommit(function () {
        print "THIS WILL BE PRINTED, BECAUSE THIS WILL BE COMMITTED\n";
    })
    ->onRollback(function () {
        print "THIS WILL NEVER BE PRINTED, BECAUSE THIS WILL BE COMMITTED\n";
    })
    ->onBuffer(function ($operation) use ($indexer) {
        print "INDEXING test2\n";
        $indexer->index($operation, 'test2');
    })
    ->setMetadata('value', 'test2');
$connection->addOperation($operation);

// Start inner transaction.
$connection->startTransaction();

$operation = (new Operation())
    ->onCommit(function () {
        print "THIS WILL NOT BE PRINTED, BECAUSE THIS WILL BE ROLLED BACK\n";
    })
    ->onRollback(function () {
        print "THIS WILL BE PRINTED, BECAUSE THIS WILL BE ROLLED BACK\n";
    })
    ->onBuffer(function ($operation) use ($indexer) {
        print "INDEXING test3\n";
        $indexer->index($operation, 'test3');
    })
    ->setMetadata('value', 'test3');
$connection->addOperation($operation);

$operation = (new Operation())
    ->onCommit(function () {
        print "THIS WILL NOT BE PRINTED, BECAUSE THIS WILL BE ROLLED BACK - second\n";
    })
    ->onRollback(function () {
        print "THIS WILL BE PRINTED, BECAUSE THIS WILL BE ROLLED BACK - second\n";
    })
    ->onBuffer(function ($operation) use ($indexer) {
        print "INDEXING test3 - second\n";
        $indexer->index($operation, 'test3');
    })
    ->setMetadata('value', 'test3 - second');
$connection->addOperation($operation);

foreach ($indexer->lookup('test1') as $operation) {
    print "Looked up test1 - found: " . $operation->getMetadata('value') . "\n";
}
foreach ($indexer->lookup('test2') as $operation) {
    print "Looked up test2 - found: " . $operation->getMetadata('value') . "\n";
}
foreach ($indexer->lookup('test3') as $operation) {
    print "Looked up test3 - found: " . $operation->getMetadata('value') . "\n";
}

// Rollback inner transaction.
$connection->rollbackTransaction();

// Commit inner transaction.
$connection->commitTransaction();
```

##### Example 4 - Value store using the indexer for lookups

[](#example-4---value-store-using-the-indexer-for-lookups)

```
namespace Gielfeldt\TransactionalPHP\Example;

require 'vendor/autoload.php';

use Gielfeldt\TransactionalPHP\Connection;
use Gielfeldt\TransactionalPHP\Indexer;

$connection = new Connection();
$indexer = new Indexer($connection);

// Start outer transaction.
$connection->startTransaction();
print "Started outer transaction\n";

$indexer->index($connection->addMetadata('value', 'value1'), 'test1');
$indexer->index($connection->addMetadata('value', 'value2'), 'test1');
$indexer->index($connection->addMetadata('value', 'value1'), 'test2');
$indexer->index($connection->addMetadata('value', 'value2'), 'test2');
print "Added data to indexer\n";

foreach ($indexer->lookup('test1') as $operation) {
    print "Looked up test1 - found: " . $operation->getMetadata('value'). "\n";
}
foreach ($indexer->lookup('test2') as $operation) {
    print "Looked up test2 - found: " . $operation->getMetadata('value'). "\n";
}

// Start inner transaction.
$connection->startTransaction();
print "Started inner transaction\n";

$indexer->index($connection->addMetadata('value', 'value3'), 'test1');
$indexer->index($connection->addMetadata('value', 'value3'), 'test2');
print "Added data to indexer\n";

foreach ($indexer->lookup('test1') as $operation) {
    print "Looked up test1 - found: " . $operation->getMetadata('value'). "\n";
}
foreach ($indexer->lookup('test2') as $operation) {
    print "Looked up test2 - found: " . $operation->getMetadata('value'). "\n";
}

// Rollback inner transaction.
$connection->rollbackTransaction();
print "Rolled back inner transaction\n";

foreach ($indexer->lookup('test1') as $operation) {
    print "Looked up test1 - found: " . $operation->getMetadata('value'). "\n";
}
foreach ($indexer->lookup('test2') as $operation) {
    print "Looked up test2 - found: " . $operation->getMetadata('value'). "\n";
}

// Easy values lookup.
var_dump($indexer->lookupMetadata('test1', 'value'));
var_dump($indexer->lookupMetadata('test2', 'value'));

// Commit inner transaction.
$connection->commitTransaction();
print "Committed outer transaction\n";

foreach ($indexer->lookup('test1') as $operation) {
    print "Looked up test1 - found: " . $operation->getMetadata('value'). "\n";
}
foreach ($indexer->lookup('test2') as $operation) {
    print "Looked up test2 - found: " . $operation->getMetadata('value'). "\n";
}
```

For more examples see the examples/ folder.

#### Features

[](#features)

- Transactionalize PHP code.
- Index operations for lookup.

#### Caveats

[](#caveats)

1. Lots probably.

###  Health Score

26

—

LowBetter than 41% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity15

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~12 days

Recently: every ~22 days

Total

8

Last Release

3602d ago

PHP version history (2 changes)0.1.0PHP &gt;=5.6.0

0.2.0PHP &gt;=5.4.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/e93f60ea3dd735998209863ed3e064b4aa440db3c23b08f44bf0655c28b0bd3c?d=identicon)[gielfeldt](/maintainers/gielfeldt)

---

Top Contributors

[![gielfeldt](https://avatars.githubusercontent.com/u/4096963?v=4)](https://github.com/gielfeldt "gielfeldt (70 commits)")

---

Tags

phpdatabasetransactionstransactional

### Embed Badge

![Health badge](/badges/gielfeldt-transactionalphp/health.svg)

```
[![Health](https://phpackages.com/badges/gielfeldt-transactionalphp/health.svg)](https://phpackages.com/packages/gielfeldt-transactionalphp)
```

###  Alternatives

[popphp/pop-db

Pop Db Component for Pop PHP Framework

1815.7k12](/packages/popphp-pop-db)[modul-is/orm

Lightweight hybrid ORM/Explorer

1118.7k](/packages/modul-is-orm)[jonas-elias/hyperf-oracle

A oracle handler for hyperf/database.

102.3k](/packages/jonas-elias-hyperf-oracle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
