Back
EMP RMI Assignment
Chinese notes Download README Download source
Slide 1

From Local SQLite to Distributed Java RMI

Turning the EMP console program into a distributed service with manual transactions, Docker deployment, and concurrency experiments.

Original stack
Java + JDBC + SQLite
Single-machine console app
Target stack
RMI client/server
Database owned by the server
Deployment
Docker on sh5
Ubuntu host with reproducible runtime

One-sentence summary

I upgraded a local employee database program into a distributed Java RMI system, then added explicit transactions and concurrent client experiments to observe SQLite behavior.

Slide 2

What the assignment required

1

Run the original EMP program

Understand the existing SQLite-backed console workflow.

2

Convert it to Java RMI

Move EMP operations behind a remote object on the server.

3

Enable manual transactions

Replace default auto-commit with explicit commit and rollback.

4

Run concurrent transaction experiments

Observe what happens when multiple clients read and write together.

Slide 3

Original program: local and monolithic

User Console menu

The user enters commands in a single Java program.

Application JDBC calls

The same process opens SQLite connections and runs SQL directly.

Storage SQLite file

Everything happens on one machine, so there is no distributed boundary.

Good for

  • Learning the schema and existing CRUD workflow
  • Single-user local execution
  • Quick verification of the EMP table

Not enough for this assignment

  • No remote interface
  • No server-side ownership of the database
  • No clean place to control transactions for many clients
Slide 4

Distributed design with RMI

Client RMI client

Calls remote methods such as list, find, or update.

Network Registry 1099 + object 2001

Fixed ports make Docker networking predictable.

Server EmpService + service layer

All SQL, transactions, and validation stay on the server side.

Data SQLite database

The database file is only accessed inside the server container.

Why the database belongs on the server

  • The client should not know JDBC or SQLite details.
  • Transaction logic stays centralized and consistent.
  • Concurrency experiments become easier to control and observe.

Remote operations exposed

  • listEmployees()
  • findEmployeeById()
  • addEmployee()
  • updateEmployee()
  • deleteEmployee()
Slide 5

Manual transactions and connection scope

Key rule

Each remote request gets its own JDBC connection. I do not share one global connection across all client threads.

  • Open connection inside the remote request
  • Set autoCommit(false) for writes
  • commit() on success
  • rollback() on failure
  • Close the connection in finally

Why this matters

  • Safer under concurrent RMI requests
  • Clear transaction boundary for each client action
  • Database remains unchanged when validation fails
  • Easy to reason about rollback behavior
conn.setAutoCommit(false); try { // execute SQL conn.commit(); } catch (SQLException e) { conn.rollback(); throw e; }
Slide 6

Docker deployment on sh5

Compose services

  • local-app for the original non-distributed version
  • rmi-server for the server and database access
  • rmi-client for normal scripted or interactive calls
  • extra clients for concurrency experiments

Practical deployment note

The remote Docker Hub mirror on sh5 returned EOF errors, so I built a small self-contained runtime bundle and deployed that image instead of relying on remote base-image pulls.

Host sh5 Ubuntu server

Docker engine runs the assignment stack.

Image Self-contained Java runtime

Jar + minimal JRE + SQLite native library support.

Outcome Reproducible execution

The same app runs without installing Java on the host.

Slide 7

Concurrent transaction experiment

Scenario A

read + read + read

Check whether concurrent readers can proceed together.

Scenario B

read + insert + update

Observe how read and write requests interleave.

Scenario C

insert + update + delete

Push the system into competing writes and watch final consistency.

What I was looking for

  • Execution order in the logs
  • Whether writes block or serialize
  • Whether commit and rollback keep the table consistent

Expected SQLite behavior

  • Reads usually coexist well
  • Writes are more limited and often serialize
  • Lock waits are valid experimental evidence, not necessarily a bug
Slide 8

Results and verification

Smoke-test results

  • Original local version runs
  • RMI server starts successfully
  • list, find, add, update, delete all work
  • The stack now runs on sh5 through Docker

Concurrent run result

In the test run, the system:

  • updated E2 from Syst. Anal. to Programmer
  • inserted E9 A. Chen Programmer
  • kept the database consistent

Key conclusion

The assignment goals were all covered: local execution, distributed RMI, manual transactions, and concurrent client behavior under SQLite.

Slide 9

Live demo plan

1. Show the running service

sudo docker compose ps

2. Read the current EMP table

sudo docker compose run --rm client-read

3. Perform one write operation

sudo docker compose run --rm client-insert

4. Optional concurrency demo

sudo docker compose up client-read client-insert client-update

Why this demo sequence works

  • It proves the server is alive first.
  • Then it shows that remote reads work.
  • Finally, it shows that remote writes change the database state.
Slide 10

Takeaways

Technical lessons

  • A local database app becomes distributed once the remote boundary is added.
  • Transaction scope must be explicit and per request.
  • SQLite can support this assignment well, but write concurrency is limited.
  • Docker made the environment repeatable across machines.

Final statement

I did not just “make it run.” I restructured the original EMP program into a client/server design, made transactions explicit, and used concurrent clients to study real database behavior.

RMI architecture Manual commit / rollback Docker deployment Concurrent experiments