Under a batch update Mysql deadlock caused by case analysis

  Recently, the deadlock shown above exception, along problem analysis and found that the problem involves a lot of the basics of business database company network now appear.

 

background:

  Use database: Mysql

  Involves Form: t_invest

  Isolation level: Repeatable Read (Repeatable Read)

  Deadlock scenario: A saveRepaymentInfo transaction () method to perform the update operation on t_invest table:

    <update id = "A" parameterType = "java.util.List">

      <foreach collecton = "list" item = "item" separator = ";">

        update t_invest

          set status = 1,

          end_date = #{item.endDate},

          period = #{item.periods},

          update_time = now()

          where invest_no = #{item.invest_no}

      </foreach>

      </update>

      invest_no field to set up a unique index

Exception information:

 

Deadlock analysis:

By positioning the business exception log tracking code found deadlock in the syncRedeemApply affairs.

Transaction syncRedeemApply will be t_invest table of the status of the batch update batch maximum number of 1000. t_invest table transaction isolation level to " Repeatable read ," In this isolation level, each index will increase row lock when an update operation , this transaction is not multi-threaded concurrent access situation exists, not because infer the concurrent operation of multiple program deadlock caused.

Business functions found through analysis of other distributed business modules at the same time status of t_invest table in saveRepaymentInfo batch update transaction, another transaction while also invest a updateExitStatusByBatch table batch updates, and are using the investno index batch update, issues It will appear here!

Methods updateExitStatusByBatch transactions batch updates on the assumption that B (), its batch updates are:

  <update id = "B" parameterType = "java.util.List">

    <foreach collecton = "list" item = "item" separator = ";">

      update t_invest

        set status = 1,

        end_date = #{item.endDate},

        period = #{item.periods},

        update_time = now()

        where invest_no = #{item.invest_no}

    </foreach>

  </update>

(In fact, Method A two transactions with sql B is the same)

 Deadlock because two or more threads in the implementation process, due to the competition for resources or A blocking phenomenon caused due communicate with each other, without external force, they will not be able to promote it. At this time, say the system is in deadlock state or system to produce a deadlock, which is always in the process of waiting for another process called the deadlock.

 As shown below:

t_fixin_invest transaction isolation level "repeatable read" row index is incremented each time will lock when the update operation is performed within a transaction if not all modifications bulk edit finished, the index will not be released, i.e. the index the row lock will not be let go, so when two transactions are updated at the same time, if there are duplicate data, there may be waiting for each other to burst deadlock.

FIG above, locked transaction syncRedeemApply i1, i3, i5, updateExitStatusByBatch transaction locked i2, i4, i6, i2 to the transaction execution syncRedeemApply update, the lock release wait updateExitStatusByBatch i2 transaction, the transaction execution updateExitStatusByBatch i1 to the updat, waiting transaction syncRedeemApply i1 release the lock, so that two transactions wait for each other, resulting in a deadlock.

My solution is to avoid using the same index update both transactional operations, to increase table t_fixin_invest a joint index (investno, pno), then one batch operations using this index update, to avoid deadlock!

 

Guess you like

Origin www.cnblogs.com/pufeng/p/12069835.html