Java多线程数据库访问

nes*_*rbu 11 java database multithreading synchronization

我想问一下什么是多线程Java应用程序的最佳解决方案,以确保所有线程同步访问db.例如,每个线程代表单独的事务,并首先检查db的值,然后根据答案必须插入或更新数据库中的某些字段(注意,插入和提交应用程序之间的注意事项正在进行其他处理).但问题是另一个线程可能在同一个表上做同样的事情.更具体的例子.线程T1启动事务,然后检查表ENTITY_TABLE是否输入代码为'111'如果发现更新其日期,如果未找到则插入新条目,然后提交事务.现在假设线程T2完全相同.现在几乎没有问题:1.T1和T2检查db并找不到任何内容并且都插入相同的条目.2. T1检查db,查找具有旧日期的条目,但在提交T2时已经更新了最近日期的条目.3.如果我们使用缓存并同步访问缓存,则会出现问题:T1获取锁定检查db和缓存,如果未找到则添加到缓存,释放锁定,提交.T2做同样的事情,发现缓存中的条目将提交.但T1事务失败并被支持.现在T2形状不好,因为它应该插入ENTITY_TABLE但不知道.还有更多?

我正在努力创建简单的自定义缓存,同步和解决问题3.但我感兴趣的是,有一些更简单的解决方案吗?有没有人必须解决类似的问题?你是怎么做到的?

Pét*_*rök 9

这应该通过配置所需的事务隔离级别主要在DB中处理.然后在此基础上,您需要选择锁定策略(乐观或悲观).

如果没有事务隔离,您将很难尝试仅在Java域中确保事务完整性.特别是考虑到即使数据库当前仅从您的Java应用程序访问,这可能在将来发生变化.

现在关于选择哪个隔离级别,从您的描述中可能看起来您需要最高的隔离级别,可序列化.然而,在实践中,由于广泛的锁定,这往往是真正的性能损失.因此,您可能需要重新评估您的要求,以便针对您的具体情况找到隔离和性能的最佳平衡.


Gil*_*anc 5

如果您想从数据库中 SQL SELECT 一行,然后更新同一行,作为 Java 开发人员,您有 2 个选择。

  1. SELECT 和 ROWLOCK,或任何适用于您的特定数据库的行锁语法。

  2. 选择该行,进行处理,就在您准备更新之前,使用 ROWLOCK 再次选择该行以查看是否有任何其他线程进行了更改。如果两个 SELECTS 返回相同的值,则更新。如果不是,则抛出错误或再次进行处理。