如何在SOA中解耦数据库实体依赖?

时间:2012-05-07 22:31:14

标签: java database-design soa

我有两个服务:TeacherService和PupilSerivce,它们共享同一个数据库。他们之间的关系是一对多,说一个老师可以有很多学生,每个学生只有一个老师。

CREATE TABLE `test`.`teacher` {
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(40),
PRIMARY KEY (`id`)
} ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `test`.`pupil` {
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`teacher_id` bigint unsigned NOT NULL COMMENT 'teacher id',
PRIMARY KEY (`id`),
CONSTRAINT `fk_teacher_id` FOREIGN KEY (`teacher_id`) REFERENCES `teacher`(`id`) ON DELETE CASCADE
} ENGINE=InnoDB DEFAULT CHARSET=utf8;

你可以想象,我有两个实体TeacherVO和PupilVO代表我的Java代码中的数据库表。

问题是,TeacherService和PupilSerivce都在单独的进程中运行并与消息通信,我不希望它们彼此之间存在任何编译依赖关系。但是,添加新瞳孔时,方法如下:

PupilService.addNewPupil(long teacherId) {
     if (isValidTeacher(teacherId) {
         // add the pupile
     }
}

这要求PupileService具有TeacherVO的知识,因此它可以进行一些验证,但是TeacherVO在TeacherService包中!

删除此类依赖关系的最佳做法是什么?

我想到了一些方法:

  1. 创建validateTeacher消息,然后PupilService将此消息发送到TeacherService并等待响应。但是,如果我有更多的要求,比如用名字搜索老师,那么我必须创建另一条消息,最后导致消息爆炸。直接搜索数据库是一种更灵活,更有效的方法,但它引入了依赖性。

  2. 如果teacher_id无效,请不要进行任何检查并捕获由外键引起的SQL异常。但是,这无法解决我可能有进一步要求的问题。

  3. 我认为,如果多个服务共享同一个数据库,这应该是SOA架构中的常见问题。我做了一段时间的研究,但没有得到任何有价值的东西。

1 个答案:

答案 0 :(得分:1)

我同意托尼·霍普金森的观点,你们要做的事情从根本上是不健全的。你无法区分老师和学生的顾虑。