2014-01-24 84 views
1

开始交易在高层次上,我有什么是这样的:MySQL的 - 锁定表或触发

所填充,并通过应用程序1.
  • A“从管理
    1. “主”数据库'数据库使用standard mechanism从“主”数据库复制的单独主机上。
    2. 应用程序2独立于应用程序1运行,对从属数据库具有非常有限的只读访问权和对其自己的独立数据库的读写访问权限。

    ,基本上需要采取什么措施是,当某些事情在“从”数据库应用改变2只需要得到通知,以便它可以检查“从”数据库的内容,写了一些东西变成自己的数据库。

    性能不是问题,在发生这种情况时锁定整个“从属”数据库是可以接受的。 关键的是要确保在应用程序2完成其任务之前,没有更多信息被复制到“从属”数据库中。应用程序2从一个独立于触发通知的会话访问“从”数据库。

    要做到这一点,我有以下触发

    delimiter // 
    CREATE TRIGGER create_report_trigger AFTER UPDATE ON jobs 
         FOR EACH ROW 
           BEGIN 
             DECLARE report_id INT; 
             IF (NEW.status = 7 AND OLD.status != 7) THEN 
               CALL CREATE_REPORT_PROC(NEW.id, @report_id); 
             END IF; 
           END; 
         // 
    delimiter ; 
    

    ...因为你不能开始交易或从一个触发器中锁定数据库,我也有以下程序

    delimiter // 
    CREATE PROCEDURE create_report_proc( 
         IN jobId INT, 
         OUT report_id INT 
    ) 
         BEGIN 
           START TRANSACTION WITH CONSISTENT SNAPSHOT; 
           SELECT CREATE_REPORT(jobId) INTO report_id; 
           COMMIT; 
         END // 
    delimiter ; 
    

    的步骤呼唤它使用的libcurl联系申请2,让它知道它需要一个user-defined function处理工作。

    当我在MySQL命令行上手动调用它时,该过程非常完美。然而,当它被从触发器调用,出现在MySQL日志以下错误:

    Explicit or implicit commit is not allowed in stored function or trigger

    ...所以显然MySQL是足够聪明来检测,我已经试图颠覆其“无锁定从触发器内部“规则中,通过将触发器委托给过程。

    用户定义的函数等待应用程序2的操作完成,然后将结果返回给其调用者,这可能是相关的(如果MySQL复制过程基本上被触发器执行阻止,则不需要手动锁定任何东西;复制过程是唯一能够对“从”数据库进行更改的东西)。

    无论如何,我想这里有两个问题:

    1. 由于触发器触发由MySQL的复制工艺制成的更新的结果,这是否意味着在复制过程被阻塞,直到触发回报?

    2. 如果不是,我该如何锁定数据库或以其他方式停止触发器的复制过程?我想从触发器内发出一个STOP SLAVE;可以做到这一点?

    编辑 - 而这里的奖金的后续问题:

    当应用2去尽自己的事情,它看到的数据没有反映,应该是在“从”的最新信息数据库。具体而言,作为触发事务的一部分对jobs表进行的任何更新对于应用程序2都是不可见的。

    为什么这是这种情况,因为触发器配置为激发AFTER UPDATE?是否有任何方法可以使新内容对数据库中的应用程序2可见,还是有必要手动收集并传递所有更新的字段值作为发送通知的一部分?

  • 回答

    2

    好了,根据我自己的研究:

    1. 触发器执行是同步的,直到触发完成阻塞调用线程。默认情况下,MySQL复制本质上是一个单线程进程(我认为即使启用多线程复制,每个数据库也只能获得一个线程)。所以在我的情况下,为了所有实际目的,阻止复制线程“锁定”数据库;除了具有写入权限的复制线程外,没有其他人。

    2. 您不明确。然而,触发器的执行被认为是触发它的事务的一部分,这意味着无论如何你都可以被隐式地锁定在原子事务中。发生这种情况的程度似乎取决于您的存储引擎和事务隔离设置。

    3. 仍然不完全确定'奖金'的问题,但我猜测它与#2有关。如果触发器的执行是触发它的事务的一部分,那么该事务在触发器完成之后才能提交。如果事务没有提交,那么其他会话的观察者将无法看到其中的任何更改。

      在任何情况下,将更新的字段作为参数传递给UDF可以很好地解决此问题。