解决方案 »

  1.   

    可直接在mysql命令行执行:show engine innodb status\G; 
    查看造成死锁的sql语句,分析索引情况,然后优化sql 
    然后 
    show processlist; 
    kill processid; 
    另外可以打开慢查询日志,linux下打开需在my.cnf的[mysqld]里面加上以下内容: 
    long_query_time = 2   
    log-slow-queries = /usr/local/mysql/mysql-slow.log
      

  2.   


    原因已经找到,是在insert某四张表的时候死锁的,表结构:
    主键是两个int类型作为联合主键,
    其他都是一些基础字段了因为表引擎用的是innodb,又同时多个进程insert同一张表,所以就死锁了请问有什么好的解决方案吗?
      

  3.   

    避免死锁的方法
    InnoDB给MySQL提供了具有提交,回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句提供非锁定读。这些特色增加了多用户部署和性能。
    但其行锁的机制也带来了产生死锁的风险,这就需要在应用程序设计时避免死锁的发生。以单个SQL语句组成的隐式事务来说,建议的避免死锁的方法如下:
    1.如果使用insert…select语句备份表格且数据量较大,在单独的时间点操作,避免与其他sql语句争夺资源,或使用select into outfile加上load data infile代替 insert…select,这样不仅快,而且不会要求锁定
    2. 一个锁定记录集的事务,其操作结果集应尽量简短,以免一次占用太多资源,与其他事务处理的记录冲突。
    3.更新或者删除表格数据,sql语句的where条件都是主键或都是索引,避免两种情况交叉,造成死锁。对于where子句较复杂的情况,将其单独通过sql得到后,再在更新语句中使用。
    4. sql语句的嵌套表格不要太多,能拆分就拆分,避免占有资源同时等待资源,导致与其他事务冲突。
    5. 对定点运行脚本的情况,避免在同一时间点运行多个对同一表进行读写的脚本,特别注意加锁且操作数据量比较大的语句。
    6.应用程序中增加对死锁的判断,如果事务意外结束,重新运行该事务,减少对功能的影响。
      

  4.   

    尽量让所有的程序按照同一先后持续来插入表。
    譬如线程1先insert A,再Insert B,而线程2 如果先Insert B,再Insert A,那么就有可能会死锁了。
      

  5.   

    sqlCmd = "insert DELAYED into tagvalue(tagdatetime, tagcode, tagval) values(?tagdatetime, ?tagcode, ?tagval)";DELAYED 使用延迟插入操作DELAYED调节符应用于INSERT和REPLACE语句。当DELAYED插入操作到达的时候,服务器把数据行放入一个队列中,并立即给客户端返回一个状态信息,这样客户端就可以在数据表被真正地插入记录之前继续进行操作了。如果读取者从该数据表中读取数据,队列中的数据就会被保持着,直到没有读取者为止。接着服务器开始插入延迟数据行(delayed-row)队列中的数据行。在插入操作的同时,服务器还要检查是否有新的读取请求到达和等待。如果有,延迟数据行队列就被挂起,允许读取者继续操作。当没有读取者的时候,服务器再次开始插入延迟的数据行。 这个过程一直进行,直到队列空了为止。