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