不对数据库层面加锁就在ORM这块加锁。不然避免不了你说描述的问题

解决方案 »

  1.   


    能否用java代码对其加锁?因为现在只是对这个项目进行优化,涉及的数据库表和存储过程太多了,不好改动
      

  2.   

    我的建议你用线程池,加semaphore来控制同时操作数据库的线程数。
    比如
    executors.newCashedThreadPool();
    看我下面写的例子,比如10个人找手机充电器,但是只有两台充电器
    给你个思路import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;public class MySemaphore extends Thread{
    Semaphore position;
    private int d;
    public MySemaphore(int i,Semaphore s){
    this.id = i;
    this.position = s;
    }

    public void run(){
    try{
    if(position.availablePermits()>0){
    System.out.println("顾客["+this.id+"]进入,有充电器");
    }else{
    System.out.println("顾客["+this.id+"]进入,没有充电器,排队");
    }
    position.acquire();
    System.out.println("顾客["+this.id+"]获得手机");
    Thread.sleep((int)Math.random()*1000);
    System.out.println("顾客["+this.id+"]使用完毕");
    position.release();
    }catch(Exception e){
    e.printStackTrace();
    }
    }

    public static void main(String args[]){
    ExecutorService list = Executors.newCashedThreadPool();
    Semaphore position = new Semaphore(2);
    for(int i=0;i<10;i++){
    list.submit(new MySemaphore(i+1,position));
    }
    list.shutdown();
    position.acquireUninterruptibly(2);
    System.out.println("全部使用完毕");
    position.release(2);
    }
    }
      

  3.   


    能否用java代码对其加锁?因为现在只是对这个项目进行优化,涉及的数据库表和存储过程太多了,不好改动
    这种情况确实不怎么好处理,特别是多个程序(进程)会对同一表操作时;
    像你这种情况,如果一个任务的处理不是很耗时,且每个任务都是独立的,就改用一个线程来处理,这样就可以解决你的问题了,也简化了问题:
    示例import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;public class SingleThreadDemo { public static void main(String[] args) {
    ExecutorService pool = Executors.newSingleThreadExecutor();
    Calculator calcu = new Calculator();
    List<Callable<Integer>> list = new ArrayList<Callable<Integer>>();

    list.add(new Task(calcu));
    list.add(new Task(calcu));
    list.add(new Task(calcu));
    list.add(new Task(calcu));

    try {
    pool.invokeAll(list);
    } catch (InterruptedException e) {
    e.printStackTrace();
    pool.shutdown();
    } finally{
    if(!pool.isShutdown()){
    pool.shutdown();
    }
    }
    }}class Task implements Callable<Integer>{

    Calculator calcu;

    public Task(Calculator calcu){
    this.calcu = calcu;
    }

    @Override
    public Integer call() {
    for(int i = 1; i <= 10; i++){
    calcu.add(i);
    calcu.sub(i);
    }
    System.out.println("结果应该是 100 --> " + calcu.getSum());
    return calcu.getSum();
    }

    }class Calculator {
    int sum = 100;

    public void add(int a){
    sum += a;
    }

    public void sub(int a){
    sum -= a;
    }

    public int getSum(){
    return sum;
    }
    }
      

  4.   

    最好使用读写锁ReadWriteLock 
      

  5.   

    我觉得以上情况要根据两方面考虑,不光是数据库要做事,程序也要分担
    1、首先程序中应该考虑并发访问的情况,我觉得最好用一些java中提供的并发操作锁和容器、队列等比如:ReentrantLock/ currentHashMap、copyOnWriteArrayList/  LinkedBlockingList等
    2、然后考虑数据库方面,我觉得最好是用乐观锁方式,这样很容易控制数据库插入和更新操作。以至于并发无障碍