返回
EMP RMI 中文提词页
English deck 下载 README 下载源码
第 1 页

把本地 SQLite 程序改成分布式 Java RMI 系统

这页你就先定调:原来是本地 EMP 小程序,我把它改成了 RMI client/server,并补上手动事务和并发实验。

原始形态
本地 Java 控制台
JDBC 直接操作 SQLite
改造后
RMI 分布式架构
client 调 server,server 管数据库
部署位置
sh5 Docker
服务器上实际可跑、可演示

怎么讲

先用一句英文总括全场:I upgraded a local EMP program into a distributed Java RMI system with explicit transactions and concurrency experiments.

第 2 页

作业到底要求什么

1

先跑原始 EMP 程序

证明本地 SQLite 版本可运行,并熟悉 EMP 表。

2

改造成 Java RMI

把 EMP 相关操作放到远程对象上,让 client 通过网络调用。

3

支持手动事务

不使用默认 auto-commit,而是显式 commit / rollback。

4

做并发实验

多个客户端同时读写,观察 SQLite 的行为。

怎么讲

这一页不要展开太多,只要强调:这个作业不只是“把代码跑通”,而是要完成 架构改造 + 事务控制 + 并发观察 三件事。

第 3 页

原始程序是本地一体化的

用户 控制台菜单

用户在一个 Java 程序里输入操作。

程序 JDBC 直接查库

应用自己打开 SQLite 连接、自己执行 SQL。

存储 本地数据库文件

所有逻辑都发生在同一台机器里,没有真正的分布式边界。

原始版本的价值

  • 可以先验证 EMP 表和 JDBC 驱动没问题
  • 方便理解已有代码和数据表
  • 是后面 RMI 版本的出发点

为什么不够

  • 没有远程接口
  • client 和数据库没有隔离
  • 事务和并发边界不清晰

怎么讲

这里一句话就够:原始版适合单机,不满足“分布式 + 并发实验”的作业目标,所以必须改架构。

第 4 页

改造后的核心设计:client 不碰数据库

客户端 RMI Client

只调用远程方法,比如 list / find / add / update / delete。

网络层 Registry 1099 + Object 2001

固定端口,Docker 里更稳定,也方便讲解。

服务端 EmpService + Service Layer

所有 SQL、校验和事务处理都在 server 端执行。

数据库 SQLite

数据库文件只由 server 访问。

为什么这样设计

  • 符合分布式系统的 client/server 结构
  • 数据库细节不会暴露给 client
  • 事务、验证、并发控制能集中在 server

你可以强调的点

  • server 才是唯一的数据所有者
  • client 只看见远程方法,不直接操作 SQLite
  • 这样更清晰,也更接近真实系统

怎么讲

这页是老师最可能追问的一页。你要明确说出: The client does not connect to SQLite directly. The server owns the database and exposes remote operations through RMI.

第 5 页

手动事务是怎么做的

实现方式

  • 每个远程请求内部自己开一个 JDBC connection
  • 写操作时调用 setAutoCommit(false)
  • 成功就 commit()
  • 异常就 rollback()
  • 最后关闭连接

为什么重要

  • 事务边界清晰
  • 多个 client 并发时更安全
  • 插入失败、title 非法等情况不会污染数据库
conn.setAutoCommit(false); try { // execute SQL conn.commit(); } catch (SQLException e) { conn.rollback(); }

怎么讲

关键表述是:I made transaction boundaries explicit on the server side. 然后再补一句:每次请求单独开连接,避免共享全局连接带来的线程问题。

第 6 页

我最后把它跑在 sh5 的 Docker 上

Compose 里的角色

  • local-app:原始本地版
  • rmi-server:服务端 + SQLite
  • rmi-client:正常远程调用
  • 多个实验 client:做并发测试

实际部署中的小坑

远端 Docker Hub 镜像源不稳定,所以我最后做了一个自包含运行时镜像,把 JRE 和 jar 一起打包,避免服务器临时拉基础镜像失败。

宿主机 sh5 Ubuntu

不需要额外安装 Java。

容器 自包含运行镜像

jar + 最小 JRE + SQLite native 依赖。

结果 稳定复现

真正能在服务器上 build 和 run。

怎么讲

如果老师只关心作业,就一句带过:Docker 保证了运行环境一致,我已经在远端服务器上实际跑通。

第 7 页

并发实验怎么做

场景 A

read + read + read

看多个读是否能同时正常完成。

场景 B

read + insert + update

看读写之间如何交错。

场景 C

insert + update + delete

看多个写操作如何竞争数据库。

主要观察点

  • 谁先执行、谁后执行
  • 写操作是否串行化
  • 最终表状态是否一致

结论预期

  • 读通常可以并发
  • 写更容易等待或串行
  • 这不是 bug,而是 SQLite 的特点

怎么讲

这里别说“完全无锁”。你要说:SQLite handled the workload consistently, but concurrent writes are naturally more constrained.

第 8 页

结果是什么

Smoke test

  • 原始本地版能跑
  • RMI server 能启动
  • list / find / add / update / delete 都成功
  • 整个系统已经在 sh5 上运行过

并发结果

  • E2Syst. Anal. 更新成 Programmer
  • 成功插入 E9 A. Chen Programmer
  • 数据库状态保持一致

一句话结论

这次作业要求的四件事我都覆盖了:原始程序、RMI 改造、手动事务、并发实验。

怎么讲

这页就是收证据。讲的时候多用 “verified on sh5” 这种表述,会显得更扎实。

第 9 页

现场 demo 就按这 3 步

1. 先看服务是不是起来了

sudo docker compose ps

2. 展示当前 EMP 表

sudo docker compose run --rm client-read

3. 做一个写操作

sudo docker compose run --rm client-insert

4. 如果老师有兴趣,再跑并发

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

怎么讲

现场不要演太多。能证明 “server 在跑、client 能读、client 能写” 就够了。并发实验可以口头讲结果,除非老师主动想看。

第 10 页

最后怎么收尾

技术收获

  • 本地数据库程序加上远程边界后,就变成分布式系统问题
  • 事务边界必须显式控制
  • SQLite 可以完成作业,但并发写天然受限
  • Docker 帮我把部署和复现做稳定了

最后一句英文

I restructured the EMP program into a client/server system, made transaction boundaries explicit, and used concurrent clients to observe real SQLite behavior.

RMI Transaction control Docker deployment Concurrency experiment

怎么讲

这页说完就可以停。老师如果提问,通常会围绕 “为什么数据库放 server 端” 和 “SQLite 并发有什么特点” 两个点展开。