在数据库中使用事务有什么问题?
从这篇文章。一个明显的问题是可伸缩性/性能。交易使用还会引发哪些其他问题?
我们能否说有两类问题,一组是长期运行的事务,另一组是短期运行的事务?如果是,我们将如何定义它们?
编辑:死锁是另一个问题,但是数据不一致性可能会更糟,具体取决于应用程序域。假设有一个值得交易的领域(使用银行来举例),那么死锁的可能性更像是为确保数据一致性而付出的成本,而不是交易使用上的问题,否则我们会不同意?如果是这样,我们将使用什么其他解决方案来确保无死锁的数据一致性?
解决方案
回答
事务的一个问题是有可能(不太可能,但有可能)在数据库中陷入僵局。我们必须了解数据库如何工作,锁定,事务处理等,以便调试这些有趣的/令人沮丧的问题。
-亚当
回答
我认为主要问题是在设计级别。我在应用程序的哪个级别上使用事务。
例如,我可以:
- 在存储过程中创建事务,
- 使用数据访问API(ADO.NET)来控制事务
- 在应用程序中使用某种形式的隐式回滚
- 分布式事务处理(通过DTC / COM +)。
在同一应用程序中使用多个级别之一似乎常常会导致性能和/或者数据完整性问题。
回答
即使不使用显式事务,我们也可能会陷入僵局。一方面,大多数关系数据库会将隐式事务应用于我们执行的每个语句。
死锁从根本上说是由获取多个锁引起的,任何涉及获取一个以上锁的活动都可能与涉及至少与第一个活动获取相同锁中的两个的任何其他活动死锁。实际上,在数据库事务中,某些已获得的锁的保存时间可能比原本要保存的时间长,直到事务结束。锁持得越久,死锁的机会就越大。这就是为什么运行时间较长的事务比较短的事务具有更大的死锁机会的原因。
回答
它在很大程度上取决于数据库内部的事务实现,也可能取决于我们使用的事务隔离级别。我在这里假设是"可重复阅读"或者更高版本。使事务长时间保持打开状态(即使是未进行任何修改的事务)会强制数据库保持频繁删除的表的已删除或者更新的行(以防万一,我们决定读取它们),否则可能会被丢弃。
同样,回滚事务可能会非常昂贵。我知道在MySQL的InnoDB引擎中,回滚大事务所花费的FAR可能比提交它要长(我们已经看到回滚需要30分钟)。
另一个问题与数据库连接状态有关。在分布式容错应用程序中,我们永远无法真正知道数据库连接所处的状态。状态数据库连接无法轻松维护,因为它们随时可能失败(应用程序需要记住它所处的状态)。进行并重做)。只需重新连接无状态的对象,并重新发出(原子的)命令,而不会(在大多数情况下)破坏状态。