CREATE OR REPLACE FUNCTION public.updatedata(userid_ integer)
RETURNS integer
AS $$
DECLARE
userdata_ integer;
BEGIN
LOOP
BEGIN
PERFORM 1 FROM public.footable f WHERE f.userid=userid_ LIMIT 1 FOR UPDATE ;
userdata_:=(SELECT f.userdata FROM public.footable f WHERE f.userid=userid_ );
UPDATE public.footable f SET userdata = userdata_ + 1 WHERE f.userid=userid_ ;
EXIT ;
EXCEPTION WHEN others THEN
END;
END LOOP;
RETURN userdata_ + 1;
EXCEPTION WHEN others THEN
END $$ language plpgsql;
当我像这样使用"lost update"
锁定时,我可以阻止用户数据列的"FOR UPDATE"
问题吗?
实际上我想首先使用serializable isolation
,但事实证明,在serializable isolation
中,只有在通信(link)之后才能检测到某些错误
答案 0 :(得分:0)
您的代码将避免丢失更新,但您可以使用简单的SQL语句实现相同的目的:
UPDATE public.footable f
SET userdata = userdata + 1
WHERE f.userid = userid_
RETURNING userdata;
没有丢失的更新,因为第一个UPDATE
将以独占模式锁定行,并且任何并发的UPDATE
都必须等到持有锁的事务完成,然后第一个UPDATE
的结果对第二个 public class Resume_game_new extends AppCompatActivity {
private RecyclerView mRecyclerView;
private CardsViewAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
List<Game> mDataset;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_resume_game_new);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view_resume_game);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter (see also next example)
mDataset = Data.bdd.getGames();
mAdapter = new CardsViewAdapter(mDataset);
mRecyclerView.setAdapter(mAdapter);
//Swipe to Delete
ItemTouchHelper swipeToDismissTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction)
{
// Do Stuff
TextView textView_id_game = (TextView) viewHolder.itemView.findViewById(R.id.textView16);
Data.bdd.remove_game(Integer.parseInt(textView_id_game.getText().toString()));
mDataset.remove(viewHolder.getAdapterPosition());
mRecyclerView.removeViewAt(viewHolder.getAdapterPosition());
mAdapter.notifyItemRemoved(viewHolder.getLayoutPosition());
mAdapter.notifyItemRangeChanged(viewHolder.getAdapterPosition(), mDataset.size());
mAdapter.notifyDataSetChanged();
}
});
swipeToDismissTouchHelper.attachToRecyclerView(mRecyclerView);
}
}
可见。