我的问题可能与Postgres非常具体,可能不是。
我无法修改的程序可以通过npgsql和一个简单的select命令访问Postgress,我所知道的。
我也可以通过npgsql访问。该表定义为:
-- Table: public.n_data
-- DROP TABLE public.n_data;
CREATE TABLE public.n_data
(
u_id integer,
p_id integer NOT NULL,
data text,
CONSTRAINT nc PRIMARY KEY (p_id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.n_data
OWNER TO postgres;
(如果该信息无论如何都是有用的) 我访问一个单独的大列,从中读取并回写它。
到目前为止一切正常。
问题是:如果我们同时写作,Postgres如何处理它。 那里有什么问题吗?
如果Postgres没有自动处理,那么当我读取数据,处理数据以及同时数据更改时,如何处理数据后,我会回写这些数据--->数据丢失。
测试数据完整性有点棘手,因为这个数据块很大,很难找到损坏。
如果这意味着什么,我用c#来做。
答案 0 :(得分:1)
锁定(在大多数 1 中)关系数据库(包括Postgres)始终位于行级别,从不在列级别(它是关系数据库中的列和行而不是“单元格“,”字段“或”记录“)
如果两个事务修改同一行,则第二个事务必须等到第一个提交或回滚。
如果两个事务修改了不同的行,那么只要它们不修改属于相同值的唯一约束或主键的列,它们就可以毫无问题地执行此操作。
Postgres永远不会通过常规DML语句阻止对数据的读取访问。所以,当一个事务修改数据时,另一个事务将看到旧数据,直到第一个事务提交更改(“读取一致性”)。
要处理丢失的更新,您可以使用可序列化隔离级别,也可以使所有事务都遵循首先需要获取行(select ... for update
)锁定的模式并保持该行直到他们完成。搜索“悲观锁定”以获取有关此模式的更多详细信息。
另一种选择是在表格中包含“已修改”的时间戳。当进程读取数据时,它还会读取修改时间戳。当它发回新的更改时,它包含where modified_at = <value obtained when reading>
- 如果数据已更改,则条件不会成立,并且不会更新任何内容,您需要重新启动事务。搜索“乐观锁定”以查找有关此模式的更多详细信息。
1某些DBMS执行页锁定,有些会将许多行级锁升级为表锁。 Postgres中的情况也不是