假设我正在开发Polling应用程序的后端。用户在轮询中选择一个选项,并且请求更新轮询文档和用户文档。
// Express endpoint for /vote/:pollId/:optionIndex
// (middleware puts users document on req.user)
function(req, res) {
//Check if the user has already voted on this poll
...
Polley.findByIdAndUpdate(req.params.pollId, {
//increment the number of votes on the selected options by one
$inc: ...
}, {
new: true
}, function (err, data) {
//If err send error message
...
// Now update the users document, so that the user
// can't vote on this poll again and so the user can go
// back and see what he/she voted for.
User.findByIdAndUpdate( req.user._id,
{
$push: {
votes: {
polleyId: req.params.polleyId,
optionIndex: req.params.optionIndex
}
}
},
function (err, user) {
// HERE IS THE PROBLEM.
// what if error happens here? Then the user will be able
// to vote on this poll one more time since the vote was not
// successfully saved in the users document.
}
);
res.status(200).json({ poll_votes: data.votes, message: "Vote Successful." });
});
}
我删除了...
部分,因为实施与问题无关。
这两项操作都需要在一次通话中进行,以便用户无权更新民意调查文件而非用户文件。
正如我在代码中所说的那样,问题在于,如果我首先更新民意调查文档并在之后更新用户文档,则第一个操作可能会成功,而第二个操作则不会。
如何确保这两项操作都失败或成功?
答案 0 :(得分:1)
MongoDB不支持不同集合和事务的原子更新。要回答你的问题,我会看到两种方法:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
ListView listViewPlaces = (ListView) rootView.findViewById(R.id.listLocality);
List<PlacesView> lstPlaceView = new ArrayList<PlacesView>();
ArrayList<PlaceModel> listPlaces = getArguments().getParcelableArrayList("listPlaces");
for (int i = 0; i < listPlaces.size(); i++)
{
Log.d("id", listPlaces.get(i).getId());
PlacesView mv = new PlacesView(listPlaces.get(i), R.layout.list_row_places);
lstPlaceView.add(mv);
}
CustomListAdapter adapter = new CustomListAdapter(lstPlaceView, rootView.getContext());
listViewPlaces.setAdapter(adapter);
return rootView;
}
(例如Google Docs)。patching way
,其中使用Tokumx为此目的不可能由于事务与线程。如果您需要支持交易并且需要使用MongoDB,我建议尝试nodejs
,因为这是解决您任务的最简单方法。