1.1 事务管理
1.1.1 由谁来控制事务
经过实践,我确定用控制器来控制事务,说白一点,就是提交和回滚。
因为实体只负责一个表的一组数据,而一个事务往往会涉及多个表的多个数据,所以实体是不行的,工厂更不用考虑,界面尽可能简单,也不适合控制事务。
1.1.2 由谁来管理事务
我在开发中采用了测试驱动的开发方法,遇到一个问题。在测试执行和实际执行时有一个重要的区别:测试执行时并不真正提交数据库保存,而实际执行时肯定要提交数据库保存。我不可能针对测试写一个类的测试版本。
这个问题的解决方法是引入了一个事务管理器。它的结构如下:
TransactionManager定义了事务管理器的接口,TransactionManager_test是测试时对此接口的实现,TransactionManager_project是项目即实际运行时对此接口的实现。可以通过配置来决定用哪个实现类。
1.1.3 保存的控制
TransactionManager只是控制commit/rollback,这样并不能保证在测试时不提交到数据库中。
因为保存是由实体来控制的,虽然实体不处理commit/rollback,但实体负责insert/update/delete。而且在PB中,连接断开时,会自动提交。所以,我们必须让程序在测试时不做insert/update/delete。而这也是TransactionManager来做的,过程见下图:
外界调用setData()保存实体,实体调用dirty()通知自己“脏”了,如果TransactionManager的实现是TransactionManager_project,则会调用实体的save()做真正的保存。如果TransactionManager的实现是TransactionManager_test,则不会调用实体的save()做真正的保存。