Delegate DBI transactions to non-JDBC drivers

Open
#1,455 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
java, perl
Domain
backend, databases

Research direction

Begin in src/main/perl/lib/DBI.pm, focusing on the non-JDBC implementations of begin_work, commit, and rollback; compare them with the DBD::Mock driver methods described in the issue. Run the direct DBD::Mock reproducer and t/csv_error.t on both JVM and interpreter backends. Done means transaction statements are delegated, bookkeeping stays consistent, JDBC behavior is preserved, and permanent success and rollback regression coverage passes.

Written by the indexing model from the issue text.

Description

bug

Summary

PerlOnJava's bundled DBI compatibility layer does not delegate begin_work, commit, or rollback to non-JDBC DBI drivers. It only changes the AutoCommit attribute in the Perl shim.

This breaks drivers that implement transaction boundaries as DBI driver methods. DBD::Mock is one such driver: it records BEGIN WORK, COMMIT, and ROLLBACK through its transaction methods. The missing delegation leaves the mock session out of sync with the DBI handle state.

CPAN failure

Archived CPAN run: 20260918-141920-96054

Distribution: DBIx-TableLoader-CSV-1.102

Target: DBIx::TableLoader::CSV

PerlOnJava reported:

t/00-compile.t ......... ok
t/00-report-prereqs.t .. ok
t/csv_error.t .......... 5 failed of 9
t/encoding.t ........... ok
t/methods.t ............ ok
t/sqlite.t ............. ok
Files=6, Tests=17, 5/17 subtests failed

All failures are in t/csv_error.t, where the test installs a DBD::Mock::Session expecting BEGIN WORK, CREATE TABLE, INSERT, and then COMMIT or ROLLBACK. Instead, the first observed SQL statement is CREATE TABLE; the session still expects BEGIN WORK.

Minimal reproducer

With DBD::Mock installed, this should consume the BEGIN WORK state before the CREATE TABLE state:

use DBI;
use DBD::Mock;
use DBD::Mock::Session;

my $dbh = DBI->connect('dbi:Mock:', '', '', {
    RaiseError => 1,
    PrintError => 0,
});

$dbh->{mock_session} = DBD::Mock::Session->new(
    txn => (
        { statement => 'BEGIN WORK', results => [[]] },
        { statement => 'CREATE TABLE test (id text)', results => [[]] },
    ),
);

$dbh->begin_work;
die "begin_work did not disable AutoCommit" if $dbh->{AutoCommit};
$dbh->do('CREATE TABLE test (id text)');

On PerlOnJava, AutoCommit becomes false, but the next statement is checked against the unconsumed BEGIN WORK state:

Statement does not match current state in DBD::Mock::Session
  got: CREATE TABLE test (id text)
  expected: BEGIN WORK

The same behavior is observable on both JVM and interpreter backends.

Oracle comparison

The unchanged focused upstream suite passes under system Perl with the exact dependency versions selected by the archived run:

t/00-compile.t .. ok
t/encoding.t .... ok
t/methods.t ..... ok
t/sqlite.t ...... ok
t/csv_error.t ... ok
All tests successful.
Files=5, Tests=16

The target and its dependencies are pure Perl/mock-driver code for this failure; no external database service or native component is involved.

Root cause

src/main/perl/lib/DBI.pm replaces the DBI transaction methods. The non-JDBC branch of DBI::begin_work checks AutoCommit, sets it to false, records BegunWork, and returns true, but never invokes the driver implementation. DBI::commit and DBI::rollback have the same problem: they clear shim bookkeeping and return true without delegating.

By contrast, DBD::Mock::db::begin_work calls prepare('BEGIN WORK') and executes it, while its commit and rollback methods issue the corresponding statements. PerlOnJava's shim bypasses those methods, so handle metadata says a transaction is active while the driver's transaction state is unchanged.

The JDBC path in src/main/java/org/perlonjava/runtime/perlmodule/DBI.java is not the direct cause; it calls the JDBC connection. The compatibility bug is the non-JDBC dispatch in the bundled Perl DBI.pm.

Related issue search

Searched existing PerlOnJava issues for DBI transaction, begin_work, DBD::Mock, AutoCommit, and commit rollback. No existing issue matched this driver-delegation problem.

Acceptance criteria

  • Non-JDBC DBI handles delegate begin_work to the driver implementation when available.
  • Non-JDBC DBI handles delegate commit and rollback likewise.
  • PerlOnJava's AutoCommit bookkeeping remains consistent with driver state.
  • The direct DBD::Mock transaction reproducer passes on JVM and interpreter backends.
  • DBIx::TableLoader::CSV 1.102's t/csv_error.t passes on both backends.
  • Add permanent project-owned regression coverage for transaction delegation, including success and rollback paths.
  • Preserve existing JDBC transaction behavior and DBI error semantics for already-active transactions.
Dominant language
Perl
Stars
64
Forks
6
Avg merge
5h 25m
Merged PRs (30d)
157

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from fglock/PerlOnJava

All issues in fglock/PerlOnJava

Similar issues

More Perl issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.