由于需要与 NoSQL 相关的事务,我决定提出自己的解决方案,针对 DynamoDB。如果您发现缺陷或改进建议,请告诉我。
前提。我将插入 2 个对象作为事务。
意义;
- 如果两个对象都没有成功插入,插入将回滚。
- 当事务正在进行时,对象将不可读取。
- 如果发生灾难性故障,例如断电,垃圾收集器将清除孤立对象。(如果事务失败,则将对象视为孤立对象。)
功能总结: 2 个对象中的每一个都将共享一个唯一的关联交易 ID。如果两个插入都成功,一个事务对象将被提交到具有成功状态的数据库。如果失败,两个对象都将被删除。
//NOTE: insert means insert into the database
// delete means delete from the database
public void InsertTwoObjects()
{
String[] transaction_object = {'random Id', '0'};
String[] a = {'object 1', transaction[0]};
String[] b = {'object 2', transaction[0]};
try{
if !(insert(a) && insert(b))
{
throw new FailedInsertException();
}
else
{
transaction_object[1]='1';
if !(insert(transaction_object))
{
throw new FailedInsertException();
}
}
}
catch(FailedInsertExpcetion e)
{
//rollback
delete a;
delete b;
delete transaction_object;
}
}
现在,我们需要定义一个新的 queryDB 函数,它将取代传统的查询函数并保持与上述事务逻辑的一致性。在另一个过程中,如果我尝试查询 a 对象,它将失败,除非事务对象返回值 1 表示成功。
public string QueryObject(String[] a)
{
String[] result = query(a);
if (result[1]==null)
{
return result[0];
}
String[] transaction = query(result[1]);
if (transaction[1]!='1')
{
throw new ItemNotFoundException();
}
else
{
return result[0];
}
}
最后一步是有一个周期性的批处理过程,类似于垃圾收集器,它将扫描数据库中超过特定年龄的孤立块并删除它们。如果事务由于电力不足而失败,阻止第一个函数执行其回滚,这是必要的。
public void BatchGargageCollect()
{
while(1==1)
{
wait(5000);
1. scan all objects with a transaction id appended to them
2. query the transaction.
3. If valid, remove the appended transaction id from the object.
}
}