1

假设您想将一些数据写入 RFID 卡并将一些数据写入数据库。从理论上讲,与数据库的连接可能随时中断,卡与读卡器之间的连接也可能随时中断。你的目标是以一种原子的方式设计它,你要么最终要么都写,要么都不写。

有什么优雅的方法可以解决这个问题吗?任何提示表示赞赏:)

(我正在使用 MS SQL Server 和 Windows 智能卡模块 (Winscard.dll),以防有什么不同)

4

3 回答 3

3

在开始更新 RFID 卡之前插入一条记录,然后在完成后更新此记录。通过这种方式,您还可以发现半完成的更新,并采取相应的行动。

  1. 向数据库中插入一条状态为“未完成”的记录。给它一个时间戳、一个唯一的 ID 以及您需要的任何其他相关信息,以唯一地描述 RFID 写入尝试
  2. 写入 RFID 卡
  3. 将步骤 1 中插入的记录更新为“已完成”或“失败”状态

然后有一个进程在超时时间过去后解决不完整的记录(通过重试,或者你想做的任何其他事情)。

与 RFID 卡通信时,请勿尝试保持打开数据库事务,因为这会:

  1. 在数据库上给你不需要的(并且可能很长的)锁
  2. 失败时回滚,这将删除您尝试对 RFID 卡做某事的任何证据
于 2012-04-23T22:17:25.130 回答
2

定义“有点”。真正的原子方式需要智能卡模块参与分布式事务,我不知道有任何智能卡 API 和/或提供者支持事务。

任何不那么原子的东西都不是原子的,你可以玩重试和状态游戏,直到奶牛回家,但除非智能卡写入是幂等的,否则在出现故障时你的正确率为零。如果智能卡写入是幂等的,那么只是重试和确认逻辑的问题:写入状态为“待定”的数据库,提交,然后写入智能卡,然后写入状态为“完成”的数据库。在崩溃时,您需要一个进程来扫描状态“待定”并重试。由于智能卡写入是幂等的,因此重试是安全的。是的,使用表作为队列在这里是相关的。

于 2012-04-23T22:38:14.433 回答
1

您需要先更新数据库,然后在数据库更新成功时预测 RFID 更新。数据库更新应该包含在事务中,以使其也具有原子性。

当然,如果后续的 RFID 更新失败,您会想要回滚数据库更新。因此,我会考虑在数据库更新中包含事务审计。如果 RFID 更新失败,您可以通过为数据库更新调用回滚例程来返回到一致状态。

希望这可以帮助!

于 2012-04-23T22:29:23.307 回答