管理多个线程访问单个数据库的各种方法有哪些?

时间:2015-11-23 06:12:27

标签: java sql database multithreading

我学到的一种方法是对这些线程使用的单个连接使用同步锁:

synchronized(LOCK){
    // use connection by current thread containing
    // critical operations that may occur simultaneously.
}

管理多个线程访问单个数据库是否还有其他更智能或更高效的方法?

例如,使用数据库引擎的内置支持数据库/表/行/等锁定? (如果是这样,如何在Java端完成?这是SELECT语句的一部分吗?还是在使用连接之前给出的某些指令?)

1 个答案:

答案 0 :(得分:2)

并发管理通常被视为数据库的一个特征(因此也是它的责任),而不是客户端代码中处理的问题(在这种情况下,“客户端”意味着“数据库的客户端”)。换句话说,如果您开始尝试在客户端代码中管理并发性,那么您实际上是在尝试管理数据库操作的 scheduling 任务,这使您在实现数据库操作的过程中占据了大约四分之一的位置。自己的代码。这不仅仅是自己编写数据库的大量工作,它可以说是编写数据库的最难部分。

考虑到这一点......

数据库管理多个并发连接,大多数数据库都具有事务功能,允许同时创建一系列游标和/或事务。最常见的情况是像Postgres这样的数据库,其中两个同时发生的事务各自拥有自己的数据视图,就像它们各自的事务开始时一样。如果所进行的操作不会相互干扰,那么它们内部发生的事情并不重要,它们都会以外部观察者始终接收数据库状态的一致视图的方式解决 - 无论是一致的结果来自于略微过时(但很快)或缓慢(但总是准确)的成本是设计中的权衡。

您确实遇到需要执行会影响数据库的大部分子集的更新的情况,并且需要将其他人锁定并迫使他们等到您的特殊操作完成(否则会发生一系列事务失败)可能的结果)。大多数数据库允许锁定模式,表,列,行等,并具有各种锁类型:插入,选择,更新等,以及临时挂起完整性检查并在锁定结束时应用它们的机制事务,以及许多其他功能,可以帮助您真正需要为数据库做一些神奇的事情。

这在客户端代码中是如何出现的?这取决于你是否在数据库中编写存储过程(以便在函数调用后隐藏一些复杂的操作),在客户端代码中手动编写查询,使用混合方法,以及数据库是否有大一组预先构建的函数,用于处理大多数需要锁定等事情的明显情况。但是,最常见的情况您绝不需要考虑大多数数据库操作的并发性

您需要建立连接。大多数情况下,这是通过创建主应用程序共享的连接池(工作线程/进程)来完成的,池库将提供队列或消息框抽象,将您的请求序列化到连接池。有时直接连接(1客户端== 1连接)方法是完全足够的(这在绝大多数情况下实际上是足够的,但我们都喜欢来展示我们在汇集方面有多棒。 ..)。有时您会有几种不同类型的应用程序同时连接到单个数据库。

考虑为本机桌面客户端提供的应用程序服务器,提供对数据库的只读访问权限的移动应用程序服务,文档导出实用程序,处理产品事务数据的仓库或POS系统以及用于处理产品事务数据的Web报告界面那个系统。一个更熟悉的案例(对我而言)是所有访问和更新中央数据源的游戏服务器,而网络论坛和“军械库”类型报告界面从其他地方访问相同的数据。没有办法在多种类型的客户端上处理客户端代码中的并发性。谢天谢地,这些功能已经内置到大多数数据库中了!