FOR UPDATE锁定postgresql 9.6

时间:2017-01-06 21:42:56

标签: postgresql serialization locking postgres-9.6

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)之后才能检测到某些错误

1 个答案:

答案 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); } } 可见。