最后胜地 2014-05-13 05:15 采纳率: 0%
浏览 4637

多线程编程中,2个线程同时调用一个存储过程…………

最近自学的时候遇到了这么一个问题……
要求是这样的:
1.在数据库中新建一个用户状态表。里面包含2个字段。user_status(userid bigint,status int)
userid为自增。
status默认为0;
插入1000条记录。

2.写一个存储过程,从user_status表中获取一条status=0的userid字段的值,取出userid时,需要同时把这条记录对应的status从0修改为1.

3.开启2个线程,在线程中循环调用第2步中的存储过程,直到user_status表中记录全部取完(即status全部为1)。要求:在2个线程中取出的userid不能重复。并把取出的userid,打印到某个文件中,一行一个userid

第一点,没啥问题吧应该,我在数据库里建好了。

第二点的话,我写的存储过程是:

create procedure sp_getuserid
as
declare @userid int
select top 1 @userid=userid from user_status where status=0 order by newid()
update user_status set status=1 where status=0 and userid =@userid
select userid from user_status where userid=@userid

第三点的代码:

public class Status implements Runnable {
    private int num;
    @Override
    public void run() {
        Boolean flag = true;
        while(flag)
        {
            flag=this.writeFile(this.getUserid());
        }
    }
    @SuppressWarnings("unchecked")
    public List<UserBean> getUserid() {
        // 创建数据库连接
        Connection conn = ConnectDb.Connect();
        QueryRunner qRunner = new QueryRunner();
        List<UserBean> list = new ArrayList<UserBean>();
        try {
            list = qRunner.query(conn, "exec sp_getuserid",
                    new BeanListHandler(UserBean.class));
        } catch (Exception e) {
            e.printStackTrace();
        }
        DbUtils.closeQuietly(conn);
        return list;
    }
    public Boolean writeFile(List<UserBean> list) {
        if (list.size()==0)
            return false;
        else {
            try {
                File file = new File("d:/test.txt");
                if (!file.exists())
                    file.createNewFile();
                FileOutputStream out = new FileOutputStream(file, true);
                for (int i = 0; i < list.size(); i++) {
                    StringBuffer sb = new StringBuffer();
                    SimpleDateFormat df = new SimpleDateFormat(
                            "yyyy-MM-dd HH:mm:ss:SSS");
                    sb.append(df.format(new Date()) + " \t"
                            + list.get(i).getUserid()+ " \t"+this.getNum());
                    sb.append(System.getProperty("line.separator"));
                    out.write(sb.toString().getBytes("utf-8"));
                }
                out.close();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return true;
            }
        }
    }
    public static void main(String[] args) {
        new Thread(new Status(1)).start();
        new Thread(new Status(2)).start();
    }
    public Status(int num)
    {
        this.num=num;
    }

}

可是到最后,我不能在txt里得到1000条数据,总是缺少一些条目,但是数据库里却更新了……

如果我把存储过程改为

create procedure sp_getuserid
as
Begin TransAction
declare @userid int
declare @errno int
set @errno=0 
select top 1 @userid=userid from user_status where status=0 order by newid()
set @errno=@errno+@@error
update user_status set status=1 where status=0 and userid =@userid
set @errno=@errno+@@error
select userid from user_status where userid=@userid
set @errno=@errno+@@error
If @errno>0 
Begin 
rollback TransAction 
end 
Else
Begin 
Commit TransAction
End 

这样运行又会报死锁错误……
好吧,多线程的问题和存储过程不怎么会啊,求指教啊!!

  • 写回答

3条回答

  • 比特山小鹿 2019-03-08 14:47
    关注

    我的这个是java+mysql 第二个问题

    DROP PROCEDURE IF EXISTS sp_status_change1;//删除之前存储过程
    DELIMITER $$

    CREATE PROCEDURE sp_status_change1()
    BEGIN
    declare maxid int;#定义变量最大的id
    declare num int;
    set @uid=1; #当前的id从0开始
    select MAX(userid) INTO maxid from user_status;#当前数据库中最大的id赋值给maxid
    SELECT userid FROM user_status where STATUS =0;
    while @uid<= maxid do #遍历查询,当前uid小于总数时,
    SELECT count(*)INTO num FROM user_status where STATUS =0 and USERID= @uid;
    if 1=num then
    UPDATE user_status
    SET STATUS=1
    where USERID= @uid;
    END IF;
    set @uid=@uid+1;
    end while;
    END$$
    DELIMITER ;

    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!