我用Java编写的RESTful服务消耗大量小文件(大约300字节),将它们写入磁盘,将它们作为BLOB插入Oracle数据库,最后删除它们。 为了防止由于网络中断而导致丢失的文件,或者如果磁盘上有多个文件,我必须将它们写入磁盘以进行批量插入。
我的问题是:如果我通过cURL
和Windows批处理运行顺序POST请求,一切都按预期工作无限时间,大约每秒3-5个文件。
如果我创建另一个批处理来对服务器/服务进行基准测试,则会将一些文件双重插入到数据库中。
它的工作方式如下:POST request (octet-stream) -> RESTful service [ -> checks for valid file -> writes to disk -> directoryscanner reads all *.XYZ files in directory into String-array -> insert into DB -> if insert OK: delete file].
我相信由于我的服务的多线程特性,如果在某个时间段(例如:几毫秒)处理两个请求,两个线程的插入过程将相同的文件插入到DB中,一个线程删除它们,第一个线程不能再找到文件了(因为thread2已经删除了它)等等。
我的问题是:如何防止这种情况发生?我开始将所有变量等创建为私有,以便其他线程无法访问它们(我确实相信它是如何工作的)。但是在两个(或所有)线程共存的非常有限的时间内,线程2和#34;窃取"来自thread1的文件,但是 AFTER thread1已经插入了它。
正如你可以推断的那样,我不是任何专业的Java程序员,所以也许你可以指出我正确的方向。如果您需要代码段或任何内容,请告诉我。
<小时/> 的修改
/service/{ID}/{file}
,其中ID是一个整数,file是请求中文件的扩展名。
我认为问题是,两个线程同时写两个文件,两个线程都将文件扫描到自己的字符串数组中,两个线程都上传文件。 (&lt; - 那我认为我可能错了)。我可以重现这个问题,甚至可以将其重新设置为3或4或5个cURL批次,然后是3或4或5文件是重复的。
EDIT2(日志示例)
2016年6月10日09:56:14.400严重[ pool-275-thread-1 ] ServiceResource.doSendData数组:file1.tst - [Ljava.lang.String; @ 3107ce05
2016年6月10日09:56:14.400严重[ pool-274-thread-1 ] ServiceResource.doSendData数组:file1.tst - [Ljava.lang.String; @ 6996e2db
答案 0 :(得分:0)
好吧,我去修改了directoryscanner部分。现在我收到文件,如果它是zip文件,将其解压缩,获取文件头,将它们插入数据库,最后如果正确传输则删除它们。如果没有与DB的连接,文件将被写入磁盘,一旦DB再次联机,就会插入到DB中。
感谢您的投入,我在这里学到了一些东西:)