在MySQL中:
我每隔一分钟清空一次表并用新数据填充它。现在我希望用户不应该在填充过程中,在确定之前或之后读取数据。
我如何实现这一目标? 是交易方式吗?
答案 0 :(得分:3)
假设您使用交易引擎(通常为Innodb),请在同一交易中清除并重新填充表格。
确保您的读者使用READ_COMMITTED或更高的事务隔离级别(默认值为REPEATABLE READ更高)。
这样,读者可以在更新期间继续阅读表格的旧内容。
有几点需要注意:
答案 1 :(得分:2)
您可以在操作期间LOCK
使用您的牌桌:
http://dev.mysql.com/doc/refman/5.1/en/lock-tables.html
表锁仅保护 其他不恰当的读写 会话。会议持有 锁,甚至读锁,都可以执行 表级操作,如DROP 表。截断操作不是 事务安全,因此发生错误 如果会话在一个期间尝试一个 积极交易或持有 桌锁。
我对MySql的内部行版本控制机制(或者实际上,如果有的话)知之甚少,但其他数据库(Oracle,Postgresql,以及最近的Sql Server)已投入大量精力允许编写者不阻止读者,只要读者可以访问在更新/写入过程开始之前存在的行的版本。提交更新后,该行的版本将变为可供所有读者使用的版本,从而避免了MySql中的上述行为将引入的瓶颈。
此策略可确保表锁定 是无死锁的。但是,有 您需要注意的其他事项 关于这个政策:如果你正在使用 LOW_PRIORITY WRITE锁定表, 它只意味着MySQL等待 这个特殊的锁直到有 没有其他想要READ的会话 锁。当会话得到了 WRITE锁定正在等待获取 锁定锁中的下一个表 表列表,所有其他会话等待 用于释放WRITE锁。如果 这成为一个严重的问题 你应该考虑你的申请 将一些表转换为 交易安全表。
答案 2 :(得分:0)
您可以根据需要将数据加载到影子表中,然后立即将影子和实际交换到RENAME TABLE:
truncate table shadow; # make sure it is clean to start with
insert into shadow .....; # lots of inserts etc against shadow table
rename table active to temp, shadow to active, temp to shadow;
truncate table shadow; # throw away the old active data
重命名语句是原子的。中间名称“temp”用于帮助交换temp和active的名称。
这适用于所有存储引擎。