当我在commercetools (文档在这里:http://dev.commercetools.com/http-api-projects-orders.html#create-order-from-cart )上从购物车创建订单时,我必须手动设置orderNumber。这个数字很重要,因为商业工具平台的内部ID是长UUID,这在履行和支付过程中是不实际的。
可靠地生成顺序递增和唯一的订单号的最佳方法是什么(在这种情况下,没有外部系统生成它们,在这种情况下,不必引入它们会很好)?
发布于 2017-12-14 22:41:50
这样做的一个好方法是使用一个自定义对象来包含您的连续订单号。在创建订单时,您可以尝试更新此自定义对象http://dev.commercetools.com/http-api-projects-custom-objects.html#create-or-update-a-customobject。如果更新成功,您可以将该数字用于orderNumber,如果更新失败,请递增并重试。
总结一下:当你要把购物车变成订单时,从你的自定义对象中获取当前的订单号。然后,尝试递增它。如果成功,则使用该数字作为订单的orderNumber。
发布于 2017-12-15 05:51:45
正如@svaj所说,您可以通过使用自定义对象来获取客户或订单的序列号。得益于版本的,自定义对象将充当锁,从而避免两个并发请求获得相同的数字。您还可以在发生并发错误时使用递归重试。
这是一个在ES6中工作的示例(同样适用于订单号)。您唯一需要设置的是序列的名称,该序列将成为自定义对象的容器和键(例如"customerSequence").
setCustomerNumber({ sequence, value, version }) {
return customObjectsService
.save({
container: sequence,
key: sequence,
value,
version,
})
.then(customObject => customObject.value);
},
getCustomerNumber(sequence) {
return customObjectsService
.find({ where: `key="${sequence}"` })
.then(({ results }) => (results.length ? results[0] : { value: 0 }))
.then(lastValue => {
return this.setCustomerNumber({
sequence,
value: lastValue.value + 1,
version: lastValue.version,
}).catch(() => this.getCustomerNumber(sequence)); // We request a new one on error
});
},这里有前面代码的单元测试
describe('when getting the next customer number', () => {
const sequence = 'customersSequence';
describe('when existing previous customer number', () => {
const oldCustomerNumber = 1;
const newCustomerNumber = oldCustomerNumber + 1;
const version = 1;
beforeEach(() => {
spyOn(customObjectsService, 'find').and.returnValue(
Promise.resolve({
results: [
{
value: oldCustomerNumber,
version,
},
],
total: 1,
}),
);
spyOn(customersService, 'setCustomerNumber').and.returnValue(
Promise.resolve(newCustomerNumber),
);
});
it('should get a customer number equals to <previous customer number> + 1', done => {
customersService
.getCustomerNumber(sequence)
.then(customerNumber => {
expect(customObjectsService.find).toHaveBeenCalledWith({
where: `key="${sequence}"`,
});
expect(customersService.setCustomerNumber).toHaveBeenCalledWith({
sequence,
value: newCustomerNumber,
version,
});
expect(customerNumber).toBe(newCustomerNumber);
})
.then(done, done.fail);
});
});
describe('when NOT existing previous customer number', () => {
const newCustomerNumber = 1;
beforeEach(() => {
spyOn(customObjectsService, 'find').and.returnValue(
Promise.resolve({
results: [],
total: 0,
}),
);
spyOn(customersService, 'setCustomerNumber').and.returnValue(
Promise.resolve(newCustomerNumber),
);
});
it('should get a customer number equals to 1', done => {
customersService
.getCustomerNumber(sequence)
.then(customerNumber => {
expect(customObjectsService.find).toHaveBeenCalledWith({
where: `key="${sequence}"`,
});
expect(customersService.setCustomerNumber).toHaveBeenCalledWith({
sequence,
value: newCustomerNumber,
version: undefined,
});
expect(customerNumber).toBe(newCustomerNumber);
})
.then(done, done.fail);
});
});
});发布于 2018-08-04 10:41:52
如果您正在用Java语言编写集成(使用CommerceTools Java SDK),那么您可以使用java.util.concurrent.atomic.AtomicLong。以下是在CommerceTools中创建订单后将订单编号设置为订单的示例。
首先在类中定义一个静态变量,如下所示
private static final AtomicLong sequence = new AtomicLong(System.currentTimeMillis() / 1000);然后可以在如下所示的方法中使用
public void setOrderNumber(Order order) throws ShoppingCartException {
long orderNumber = sequence.incrementAndGet();
// command to set order number
SetOrderNumber action = SetOrderNumber.of(String.valueOf(orderNumber));
OrderUpdateCommand command = OrderUpdateCommand.of(order, action);
// execute the command
try {
// some code to get a Java SDK client
BlockingSphereClient client = ...;
this.order = client.executeBlocking(command);
} catch (Exception e) {
// log/throw exeception
}
}https://stackoverflow.com/questions/34356580
复制相似问题