最近正在看spring in action里对事务的实现,读书之余也在考虑给这个ORM加上事务的功能,并集成到spring里去,从而加深对自己对事务的理解, 也让这个ORM工具更加完善。
实现方式
这一章我们先抛开spring事务不谈,从最简单的JDBC单库事务开始考虑如何让这个ORM工具实现对事务的支持。
1、定义SimpleTransaction类
SimpleTransaction类有两个属性:
transCon和preparedStatement
其中transCon用来存连接串,preparedStatement用来存PreparedStatement对象。
然后有一个commit()方法和一个rollback()方法。
2、修改BaseDao类
在BaseDao类里, 我们需要重载下add方法:
增加了这个重载的方法之后,
需要事务的时候,我们可以通过dao.add(foodInfo, simpleTransaction)来执行add操作。
不需要事务的时候, 我们就可以通过dao.add(foodInfo)来执行add操作,并且不需要捕获异常。
我们再把ExecuteUpdate()方法,加上一个类型为SimpleTransaction的参数。
我们可以看到里面有个逻辑:当simpleTransaction为空的时候, 执行完成之后,是会直接调DBUtil的close()方法的。
这是因为如果使用事务,关闭PreparedStatement和Connection的工作都是在rollback()或者commit()里完成的。而如果不是用事务的时候,就需要在ExecuteUpdate里做了。
3、修改DBUtil类
修改DBUtil类里的executeUpdate()方法和init()方法。
init()方法里, 我们判断如果是使用事务,并且simpleTransaction里的连接串不是空的时候, 我们就会用事务里已经有的连接串作为下一个sql的连接串。这是支持事务最核心的地方。
同样,executeUpdate()方法在simpleTransaction不为空的时候, 也会将prepareStatement存到simpleTransaction里去,便于将来执行rollback和close。
实验结果
测试方法和事务的使用方法:
使用方法里, 需要new一个SimpleTransaction的实例,作为两次add的参数传进去,然后add之后再提交这个实例,也就是simpleTransaction.commit();
执行结果如下:
最重要的,数据没有插入进去。
小结
通过上面的实验, 我们可以认为这个简单的ORM开始能够支持单库的事务。但是,我们知道,一般事务的属性包括五个方面:传播行为、隔离规则、是否只读、超时时间、回滚规则。在我们这个简单实现里,要么被默认了,要么被写死了。并且这种事务的实现方式用起来有点麻烦,没有spring的方便。所以,这个简单的事务实现方式,只适合学习用, 真正应用到生产肯定是不行的。
下一章,我们会将sping整合到这个ORM工具里去,包括数据源的整合和事务的整合,从而用spring的统一标准来解决以下两个问题:
1、连接池的问题。
2、事务的这5个属性不可配置的问题。