2012-06-28 41 views
4

我的问题是,我不时想删除来自Java的Azure表的内容。该表拥有数百万行,因此它似乎不是逐个删除所有实体的好方法(因为有很多REST API调用)。Azure Tables删除并创建表失败

我试图删除,然后再次创建表,但我的代码失败。

getTableClient().deleteTableIfExists("tablename"); 
getTableClient().createTableIfNotExists("tablename"); 

这里是我的堆栈跟踪:

com.microsoft.windowsazure.services.table.client.TableServiceException: Conflict 
at com.microsoft.windowsazure.services.table.client.TableServiceException.generateTableServiceException(TableServiceException.java:57) 
at com.microsoft.windowsazure.services.table.client.TableOperation$2.execute(TableOperation.java:339) 
at com.microsoft.windowsazure.services.table.client.TableOperation$2.execute(TableOperation.java:322) 
at com.microsoft.windowsazure.services.core.storage.utils.implementation.ExecutionEngine.executeWithRetry(ExecutionEngine.java:110) 
at com.microsoft.windowsazure.services.table.client.TableOperation.performInsert(TableOperation.java:374) 
at com.microsoft.windowsazure.services.table.client.TableOperation.execute(TableOperation.java:551) 
at com.microsoft.windowsazure.services.table.client.CloudTableClient.execute(CloudTableClient.java:638) 
at com.microsoft.windowsazure.services.table.client.CloudTableClient.createTable(CloudTableClient.java:173) 
at com.microsoft.windowsazure.services.table.client.CloudTableClient.createTableIfNotExists(CloudTableClient.java:251) 
at com.microsoft.windowsazure.services.table.client.CloudTableClient.createTableIfNotExists(CloudTableClient.java:197) 

我必须一会儿之间睡觉两个电话?我宁愿在这里等待,因为我希望尽可能缩短这个操作的时间,以便其他线程可以在表中再次写入。

还是有安全的方法来做到这一点?在Azure中的表使用尽可能少的REST API调用尽可能DELETE FROM tablename;


编辑

是的,我正在寻找的SQL语句的等效。

我目前最好的拍摄是:

getTableClient().deleteTableIfExists("tablename"); 
// TODO: solve problem with new creation! 
boolean success = false; 
while (!success) { 
try { 
    success = getTableClient().createTableIfNotExists("tablename"); 
} catch (StorageException e) { 
    System.err.println("Log table recreation failed retrying in 5 sec"); 
    try { 
    Thread.sleep(5000); 
    } catch (InterruptedException ex) {} 
} 

我找一个更好,更安全的解决方案,然后这个!

+0

不,你正在寻找SQL Drop Table。您不希望被实体(行)删除,因为这可能是多个(结算)事务。删除表是一个事务。 – Paparazzi

回答

8

对Windows Azure的表中的删除操作是不是一个即时操作。当删除请求发出后,它是由存储服务,并且不再标记为删除可能需要在后台删除(垃圾收集),这可能需要几秒钟的时间才能完成

您会得到一个409(冲突),因为当代码请求新的表时,表仍然存在表被创建为相同的名称。

请参阅备注区域n(页面底部)的MSDN文档http://msdn.microsoft.com/en-us/library/windowsazure/dd179387.aspx

除了等待(像你已经完成)或创建一个不同名称的表,我不知道替代。

+2

这很可能是发生了什么事情。实际上,您应该在线路上收到错误消息,表示该表格也将被删除。你会看到它在一个.NET客户端的异常,不知道为什么你没有看到它在Java客户端。此外,大型表格可能需要很多*分钟*(而不是数秒)才能被垃圾收集。对于非常大的桌子,我在某些情况下看过40分钟以上。 – dunnry

0

你不能使用一个删除REST调用delete a table

+0

我确实使用一次调用来删除表...而另一次再次添加它。正如@Will指出的,我的目标是从表中删除所有数据。它在Azure表API中没有等效。 – hpityu

+0

啊我看到我误解了你的问题,看起来像它不可能atm,也许有一天可能更新这个答案。 – tsukimi

0

您希望得到SQL DELETE FROM table;TRUNCATE TABLE table;的等值。

https://stackoverflow.com/a/8920072/15721说,有没有办法这个:(

+0

这正是我想要做的。这就是为什么我要删除并重新创建表格。我不明白的是为什么我在顺序执行这些时遇到冲突。 – hpityu

2

@mcollier对这里的原因是正确的,但我想指出一个可能的解决方案。每当我们面对一个我们知道我们会有大量想要偶尔修剪的表格数据的场景时,我们通过滚动表格来设计它。因此,我们定期增加表名或将其中的日期存入日常数据(例如logs20120628)。然后我们可以在不影响当前表的情况下删除整个表,或者在我们重新创建表之前强制等待(有时等待非常长的时间)。

只需在表格命名中设计一点灵活性,这对您而言不是什么大问题。