繁体   English   中英

Spring事务并插入数据库

[英]Spring transactions and inserting into database

我有一个设计问题。 考虑一个在多个集群环境中运行的应用程序,假设有3个集群。 该应用程序侦听目录,并处理在那里导出的所有新文件,并将其发送到文档管理系统。 我只希望一个集群处理给定的文件,这样我就可以避免出现竞争情况。 为此,我创建了一个称为DocumentLock的锁表,以便可以将数据库用作仲裁程序。 3列分别是guid(主键),文件id(这是来自唯一的文件名),锁定时间戳。 我正在使用Spring事务,并使用Oracle作为数据库。 我打算使用Read_Committed隔离级别。

因此,假设集群A拥有文件A,同时集群B也拥有文件A。现在,使用事务A的集群A将尝试插入DocumentLock表中,并说它是成功的。 因此,我在DocumentLock表中将有1行,唯一的ID是文件A(文件名)。 现在,同时使用Tx-B的群集B尝试将记录插入到DocumentLock表中,但是它需要等到Tx-A被提交,因为我正在使用'Read_Committed'隔离级别。因此TX-B将处于等待状态州。 一旦提交了Tx-A,现在Tx-B将尝试插入相同的记录(文件A),并且由于它违反了唯一约束,因此将引发错误。

我对Read_committed的理解正确吗?

我试图避免多个群集在表中插入相同的文件(唯一记录),所以我假设如果两个事务开始同时开始插入相同的文件名,则其中一个需要等到另一个提交后再进行? 那么Oracle如何确定哪个Transaction(Tx-A或Tx-B)获取表的保持(锁定)? 同样在Read_committed中,整个表是否被锁定,还是仅行?

另外,如果群集B拥有另一个文件,例如文件B,则应将其插入DocumentLock中而不会出现任何问题,因为群集A正在处理文件A,群集B需要处理文件B。感谢您的帮助

我提供替代方法来解决此问题。

将隔离级别设置为READ UNCOMMITTED。 这将确保其他事务也准备好对数据库的所有未提交的更新。 这种方法的好处是,从一个群集向数据库中的任何插入都将立即为所有其他群集所访问。 这样一来,就可以放置一些应用程序逻辑来确定谁应该获得该锁。

让我们来案例。

情况1:群集A和B试图锁定文件F

  • 群集A希望保留文件F。

  • 群集A在数据库中搜索以查看是否有人已经获得了锁。

  • 群集A拥有文件F并将记录插入表中,但尚未提交事务

  • 群集B希望保留文件F。

  • 集群B在数据库中搜索并找到集群A插入的条目
    即使没有提交。

情况2:群集A和B试图锁定文件F1和F2

  • 群集A希望保留文件F1。
  • 群集A在数据库中搜索以查看是否有人已经获得了锁。
  • 群集A拥有文件F1并将记录插入表中,但尚未提交事务
  • 群集B希望保留文件F2。
  • 群集B在数据库中搜索以查看是否有人已经获得了锁。
  • 群集B拥有文件F2,并将记录插入表中,但尚未提交事务。
  • 群集A和群集B在那里提交事务。

我不太确定集群A是否未提交文件f记录的插入,在这种情况下,如果集群B也正在插入文件f的记录,数据库将抛出唯一性错误。 因此,这种检查应用程序逻辑中所有内容的变通办法会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM