使用find()方法验证这两个操作已经成功:
mongo会返回两个类似下面的文档:
事务过程:
设置事务初始状态initial:
通过插入下面的文档创建transaction集合,transaction文档持有源(source)和目标(destination),它们引用自accounts集合文档的字段名,以及value字段表示改变balance字段数量的数据。最后,state字段反映事务的当前状态。
验证这个操作已经成功,使用find():
这个操作会返回一个类似下面的文档:
切换事务到Pending状态:
在修改accounts集合记录之前,将事务状态从initial设置为pending。使用findOne()方法将transaction文档赋值给shell会话中的局部变量t:
变量t创建后,shell将返回它的值,将会看到如下的输出:
使用update()改变state的值为pending:
find()操作将返回transaction集合的内容,类似下面:
将事务应用到两个账户:
使用update()方法应用事务到两个账户。在update()查询中,条件pendingTransactions:{$ne:t._id}阻止事务更新账户,如果账户的pendingTransaction字段包含事务t的_id:
find()操作将返回accounts集合的内容,现在应该类似于下面的内容:
设置事务状态为committed:
使用下面的update()操作设置事务的状态为committed:
find()操作发回transactions集合的内容,现在应该类似下面的内容:
移除pending事务:
使用下面的update()操作从accounts集合中移除pending事务:
find()操作返回accounts集合内容,现在应该类似下面内容:
设置事务状态为done:
通过设置transaction文档的state为done完成事务:
find()操作返回transaction集合的内容,此时应该类似下面:
从失败场景中恢复:
最重要的部分不是上面的典型例子,而是从各种失败场景中恢复未完成的事务的可能性。这部分将概述可能的失败,并提供方法从这些事件中恢复事务。这里有两种类型的失败:
1、所有发生在第一步(即设置事务的初始状态initial)之后,但在第三步(即应用事务到两个账户)之前的失败。为了还原事务,应用应该获取一个pending状态的transaction列表并且从第二步(即切换事务到pending状态)中恢复。
2、所有发生在第三步之后(即应用事务到两个账户)但在第五步(即设置事务状态为done)之前的失败。为了还原事务,应用需要获取一个committed状态的事务列表,并且从第四步(即移除pending事务)恢复。
因此应用程序总是能够恢复事务,最终达到一个一致的状态。应用程序开始捕获到每个未完成的事务时运行下面的恢复操作。你可能还希望定期运行恢复操作,以确保数据处于一致状态。达成一致状态所需要的时间取决于应用程序需要多长时间恢复每个事务。
回滚:
在某些情况下可能需要“回滚”或“撤消”事务,当应用程序需要“取消”该事务时,或者是因为它永远需要恢复当其中一个帐户不存在的情况下,或停止现有的事务。这里有两种可能的回滚操作:
1、应用事务(即第三步)之后,你已经完全提交事务,你不应该回滚事务。相反,创建一个新的事务,切换源(源)和目标(destination)的值。
2、创建事务(即第一步)之后,在应用事务(即第三步)之前,使用下面的处理过程:
设置事务状态为canceling:
首先设置事务状态为canceling,使用下面的update()操作:
撤销事务:
使用下面的操作顺序从两个账户中撤销事务:
find()操作返回acounts集合的内容,应该类似下面:
设置事务状态为canceled:
最后,使用下面的update()状态将事务状态设置为canceled:
参考资料:http://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/
希望本文所述对大家MongoDB数据库程序设计有所帮助。